Databases 7 min read

Why Insert‑Into‑Select Can Crash Your MySQL and How to Prevent It

A real‑world MySQL incident shows that using INSERT INTO SELECT without proper indexing can trigger full table scans, lock tables, cause OOM and data loss, while a careful analysis and adding indexes can safely resolve the issue.

macrozheng
macrozheng
macrozheng
Why Insert‑Into‑Select Can Crash Your MySQL and How to Prevent It

Background

The company processes millions of rows daily in a single MySQL table and needed to migrate old data without sharding.

Proposed solutions

Load data via a program, insert into a history table, then delete the original rows.

Use

INSERT INTO SELECT

to let the database handle the migration.

The first method caused an OOM error when loading all data at once, so the team chose the second method.

What went wrong

Typical pseudo‑code for the first approach demonstrates loading the entire result set into memory:

<code>// 1. Query data to migrate
List&lt;Object&gt; list = selectData();

// 2. Insert into history table
insertData(list);

// 3. Delete original rows
deleteByIds(ids);
</code>

During the nightly migration the team used

INSERT INTO SELECT

with a date filter (retain only the last 10 days). The SELECT part performed a full table scan, locking the target table and causing intermittent insert failures, which resulted in missing payment records.

The execution plan clearly shows a full table scan.

Root cause analysis

In the default transaction isolation level,

INSERT INTO a SELECT b

locks table

a

while scanning

b

row‑by‑row; the full scan caused extensive locking and timeouts.

Testing missed the issue because the test environment used realistic data volume but did not simulate the large‑scale nightly insert, so the problem only appeared in production.

Solution

Avoid full table scans by adding appropriate indexes on the columns used in the

WHERE

clause of the SELECT statement, ensuring the query uses the index and does not lock the whole table.

Conclusion

Use

INSERT INTO SELECT

with caution; always verify that the SELECT part is indexed and consider its impact on transaction isolation to prevent OOM and data loss.

IndexingMySQLINSERT INTO SELECTdatabase performanceFull Table Scan
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.