MySQL - 如何优化长时间运行的查询

时间:2014-10-22 15:23:10

标签: mysql sql

我的查询需要很长时间才能完成。我想知道是否有任何优化它,以便它会更快地运行。目前该表有大约1500万行,并且在expirationDate上有索引。此查询已运行8000+秒。

UPDATE LOW_PRIORITY items
SET    expire = 1
WHERE  expirationdate < Curdate()
       AND expirationdate != '000-00-00'
       AND expire = '0'
       AND ( `submit_id` != '742457'
              OR submit_id IS NULL )  

1 个答案:

答案 0 :(得分:0)

别介意你的表结构(我在编辑之前请求它),我有一个解决方案。我之前在我们的生产mySQL数据库上多次使用我的DBA完成了这项工作,即使在一天的高峰时段也是如此。您需要采取的方法是进行一次大量的UPDATE查询(在执行时将锁定表)并将其转换为多个单独的更新。这些单独的更新不会对您的数据库产生重大影响,特别是如果您以较小的批次运行它们并将其分解。

要生成这些单独的查询,请运行此项(假设项目表的主键名为&#34; id&#34;):

SELECT CONCAT(
  ‘UPDATE items SET expire = 1 WHERE id = ‘, 
  items.id,
  ‘;’) AS ''
FROM items
WHERE expirationdate < Curdate()
AND expirationdate != '000-00-00'
AND expire = '0'
AND ( `submit_id` != ‘742457'
OR submit_id IS NULL )   

这将生成如下所示的SQL:

UPDATE items SET expire = 1 WHERE id = 1234;
UPDATE items SET expire = 1 WHERE id = 2345;
.....

我个人喜欢将上述查询放在文本文件中并从命令行运行:

cat theQuery.sql | mysql -u yourusername [+ command line args with db host, etc] -p > outputSQLCommands.sql

这会将查询传递给mySQL并将结果转储到输出文件。如果您注意到,我们将输出中的列命名为&#39;&#39; (没有)。这使得输出在文本文件中格式很好,因此可以很容易地将其转储回mySQL来运行命令。事实上,你可以一举这样做:

cat theQuery.sql | mysql -u yourusername [+ command line args with db host, etc] -p | mysql -u yourusername [+ command line args with db host, etc] -p

然后你肯定是在打球。 SQL风格。

输出SQL文件后,如果查询的查询次数过多,可以使用命令行工具,例如&#34; split&#34;将文件拆分成一堆较小的文件。

我建议您根据数据库的硬件/性能等进行测试以找到最佳批量大小。例如,首先尝试运行1000个更新,如果这样做没有重大影响,请尝试5000等。然后,您可以将文件的其余部分拆分为您熟悉的块并运行它们。

祝你好运!