为什么MySQL'插入... select ...'比单独选择要慢得多?

Ben*_*Ben 11 mysql performance temp-tables insert-into mysql-cluster

我正在尝试将查询结果存储在临时表中以供进一步处理.

create temporary table tmpTest
(
    a FLOAT,
    b FLOAT,
    c FLOAT
)
engine = memory;

insert into tmpTest
(
    select a,b,c from someTable
    where ...
);
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,插入需要一分钟,而单独的子选择只需要几秒钟.为什么将数据写入临时表而不是将其打印到我的SQL管理工具的输出需要这么长时间?

更新 我的设置:MySQL 7.3.2集群,带有8个Debian Linux ndb数据节点1个SQL节点(Windows Server 2012)

我正在运行select on的表是一个ndb表.

我试图找出,如果执行计划在使用'insert into ..'时会有所不同,但它们看起来一样:(抱歉格式化,stackoverflow没有表格)

id  select_type     table       type    possible_keys   key     key_len ref                 rows        Extra
1   PRIMARY         <subquery3> ALL     \N              \N      \N      \N                  \N          \N
1   PRIMARY         foo         ref     PRIMARY         PRIMARY 3       <subquery3>.fooId   9747434     Using where
2   SUBQUERY        someTable   range   PRIMARY         PRIMARY 3       \N                  136933000   Using where with pushed condition; Using MRR; Using temporary; Using filesort
3   MATERIALIZED    tmpBar      ALL     \N              \N      \N      \N                  1000        \N

CREATE TABLE ... SELECT也很慢.47秒与5秒没有表插入/创建.

Don*_*ool 6

我在上面写了一条评论,然后偶然发现了这个作为解决方法。

这将完成你想做的事情。

SELECT * FROM aTable INTO OUTFILE '/tmp/atable.txt';
LOAD DATA INFILE '/tmp/atable.txt' INTO TABLE anotherTable;
Run Code Online (Sandbox Code Playgroud)

请注意,这样做意味着以某种方式管理 /tmp 表。如果您尝试将数据选择到已存在的 OUTFILE 中,则会收到错误。所以你需要生成唯一的临时文件名。然后运行某种 cron 作业来清理它们。

我猜 INFILE 和 OUTFILE 的行为不同。如果有人可以阐明这里发生的事情来解释 mysql 行为,我将不胜感激。

D

这是比使用 INFILE / OUTFILE 更好的方法。

设置事务隔离级别已提交读;INSERT INTO aTable SELECT ... FROM ...

这里有一篇相关的文章可供阅读:

如何改进 INSERT INTO ... SELECT 锁定行为


Ben*_*ght 0

原因与计算机的读写方式以及临时文件的工作方式有关。Select 正在读取硬盘驱动器上索引文件中的数据,而 insert 正在使用临时文件并写入该文件。需要更多的 RAM,而且这样做也更困难。至于为什么需要一分钟,我不太确定,但我认为代码可能有点不正确,所以这会有所帮助。

  • 你有没有得到这个问题的答案?或者弄清楚如何提高性能?我得到了相同的行为,其中 SELECT 需要亚秒,但 INSERT 需要 30 秒。这完全令人困惑。我想知道这是不是一个错误?为了解决这个问题,我尝试在我正在选择并插入一行的数据上创建一个游标,而且速度更快。这太疯狂了。我会尝试一个与你类似的问题,但似乎没有答案。 (5认同)