我的查询需要很长时间才能完成。我想知道是否有任何优化它,以便它会更快地运行。目前该表有大约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 )
答案 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等。然后,您可以将文件的其余部分拆分为您熟悉的块并运行它们。
祝你好运!