为什么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
相关文章