2

精简版:

INSERT INTO SELECT 插入到具有相同数据的全文索引的表中有时需要 25 秒,有时需要 2500 秒。我们不知道这个巨大的差距是从哪里来的。

长版:

我有一个 cronjob 的问题,它将新数据导入到导入表中,并通过 INSERT INTO SELECT 语句将这些数据复制到生产表中。我已经拆分了表,因为使用 mysql 全文索引进行更新需要时间 - 使用一个 INSERT INTO SELECT 将数据插入到该表中似乎比使用许多单个插入语句更快

导入新数据的 cron 每 5 分钟运行一次。有一个函数可以检查 cron 的实例是否正在运行以禁止脚本的并行运行。通常每次 cron 调用都会有大约 500 条新记录。晚上 1 点到 2 点有更多的新数据(大约 5.000 – 15.000 条新记录),并且 cron 运行的时间远远超过 5 分钟。

当 cron 在夜间长时间运行并跟踪这些查询的性能时,我检测到 INSERT INTO SELECT 语句的性能非常(!)慢。要复制大约 15.000 条新记录(文件大小约为 30 MB),查询需要超过 2.500 秒!

查询是:

INSERT IGNORE INTO mentiondata 
SELECT * FROM mentionimport 
WHERE id <= 1203780;

我分析查询并得到以下结果:

2012-10-31 06:52:06 Queryprofile: {
"starting":"0.000036",
"checking permissions":"0.000003",
"Opening tables":"0.000132",
"System lock":"0.000003",
"Table lock":"0.000007",
"init":"0.000041",
"optimizing":"0.000007",
"statistics":"0.000023",
"preparing":"0.000005",
"executing":"0.000002",
"Sending data":"999.999999",
"end":"0.000017",
"query end":"0.000005",
"freeing items":"1.458159",
"logging slow query":"0.000050",
"cleaning up":"0.000007"}

在进程列表中,发送数据超过 2.500 - 在配置文件中仅为 999.999999。也许这就是探查器限制——随便……</p>

真正奇怪的是:当我尝试通过从全文表中删除记录来重现问题时(删除来自提及数据 WHERE id >= 1203780;)并手动启动复制过程只需要大约 25 秒!!!

所以我不明白,我真的需要帮助!我不明白为什么同一个查询之间会有如此大的性能差异!我在 cron-copy-statement 运行时检查了 mysql-processlist——没有其他查询会锁定表或其他东西。进程列表中只有一个复制查询——以及超过 2.500 秒的“发送数据”。没有其他 cron 或任何其他任务会影响服务器运行的性能。似乎 mysql-server 每晚都会变慢,或者在插入语句发生之前很长时间打开连接时 sql-query 需要很长时间(将数据插入到复制导入表中)。

是否有任何状态变量我可以检查为什么 mysql 这么慢?是否有可能检查为什么这些查询如此缓慢?这里有一些服务器变量的信息:

bulk_insert_buffer_size: 268435456
key_buffer_size: 536870912
query_cache_size: 536870912

谢谢你的帮助!

蒂莫

4

0 回答 0