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

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

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

insert into tmpTest
(
    select a,b,c from someTable
    where ...
);

但由于某些原因,插入操作最多需要一分钟,而仅子选择操作只需要几秒钟。为什么将数据写入临时表而不是打印到我的SQL管理工具的输出要花这么长的时间?

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

我正在运行SELECT的表是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
创建表格...SELECT速度也很慢。47秒,而不插入/创建表时为5秒。


解决方案

我在上面写了一条评论,然后偶然发现这是一种解决办法。

这将完成您想要做的事情。

SELECT * FROM aTable INTO OUTFILE '/tmp/atable.txt';
LOAD DATA INFILE '/tmp/atable.txt' INTO TABLE anotherTable;

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

我猜INFILE和OUTFILE的行为不同。如果有人能解释一下MySQL的行为是怎么回事,我将不胜感激。

D

这里有一种比使用INFILE/OUTFILE更好的方法。

设置事务隔离级别读已提交; 插入到表格中 选择...发件人...

这里有一篇相关的帖子可供阅读:

How to improve INSERT INTO ... SELECT locking behavior

相关文章