我有一个cronjob,每5分钟执行一次长时间运行的查询。此查询不是时间关键,目前大约需要30秒才能完成。
问题在于,在执行查询时,所有其他查询的运行速度都要慢得多。
查询非常简单(没有连接,使用索引等)但是读取了大量数据(1.5 mil行,每行约150个字节的数据)。
我无法轻松缓存结果,因为所有数据都可以随时更改。
有没有办法限制这个特定的查询?
修改 查询真的只是:
SELECT field1,field2 FROM table;
编辑2: 好的,很抱歉这样说,但是你们每个人都错过了这一点。我问我是否可以限制查询,我得到的所有答案都没有解决问题。你们都告诉我改变cronjob(我知道我可以),从cli运行它(我不想),以块的形式获取数据等。
我再次具体要求我可以以某种方式执行MySQL SELECT查询“不重要”,这样它就不会从其他查询中窃取所有资源吗?
对不起,如果这听起来像是一个主要的咆哮,我很感谢你花时间来帮助:)
答案 0 :(得分:2)
Google对您所面临的同一问题提出了this回答。本文描述了一个读取整个表的查询,并使用了大量的I / O;解决方案是一次读取1000行,然后休眠一段时间来检索这些行。
我不确定这是否能解决您的问题,但它似乎是一个可靠的解决方案。
以下代码会从链接中复制并稍加修改以回答您的问题:
SELECT
field1, field2,
CASE
WHEN (@row_counter := @row_counter + 1) IS NULL THEN NULL
WHEN @row_counter % 1000 = 0 THEN
CASE
WHEN (@time_now := SYSDATE()) IS NULL THEN NULL
WHEN (@time_diff := (TIMESTAMPDIFF(SECOND, @chunk_start_time, @time_now))) IS NULL THEN NULL
WHEN SLEEP(@time_diff) + test.prove_it(CONCAT('will sleep for ', @time_diff, ' seconds')) IS NULL THEN NULL
WHEN (@chunk_start_time := SYSDATE()) IS NULL THEN NULL
ELSE 0
END
ELSE 0
END AS rental_id,
TIMESTAMPDIFF(DAY, rental_date, return_date) AS rental_days
FROM
table,
(SELECT @row_counter := 0) sel_row_counter,
(SELECT @chunk_start_time := NOW()) sel_chunk_start_time
;
答案 1 :(得分:1)
您可以在PHP中创建一个循环并以100,000个行的批量检索数据,每个批次之间的睡眠时间为几毫秒。不完美但这会给其他查询带来更多机会。
答案 2 :(得分:1)
从MySQL服务器获取五个megarows到客户端(cronjob进程)在三十秒内发出此查询是不错的表现。你不会稍微改善它。
(我想你可以投资超高性能数据中心设备来改进它;在这种情况下你可能会加倍它。这还不足以解决每五分钟一次的减速问题。)
您的系统放慢速度的原因是MySQL正在尝试将一致的结果返回到您的SELECT
操作。当它将您的结果推送给您的客户时,它会对您的表格进行排队或延迟插入和更新。
你怎么能打败这个问题?最好的方法是修复cronjob进程。理想的情况是在数据库系统中而不是在cronjob中运行计算。就是这样的。
SELECT SUM(column) AS colsum, MAX(column2) AS colmax, DATE(timecolumn) AS day
FROM table
GROUP BY DATE(timecolumn)
您还没有告诉我们您的cronjob在这五百万行中做了什么,所以我只是将此查询作为示例。这种事情将处理表,但返回FAR更少的行。它也可以进行优化。
第二个最佳解决方案是按块而不是一起检索行块。
另一种解决方案是将表格切换为MyISAM。这摆脱了事务语义。它可能会破坏你的应用程序的其余部分。
如果需要,您还可以构建一个从属MySQL服务器以用于此类报告查询。
现在也许你不能改变cronjob或基础设施。如果您无法进行任何算法或基础结构更改,则可能有http://thedailywtf.com/的候选人。没有什么魔力可以使海量数据传输速度提高数百倍。
答案 3 :(得分:-1)
如果您可以完全从命令行调用查询(假设您在Linux / UNIX / OS X系统上运行),则可以使用nice
来降低调度优先级,例如:
nice -n 19 mysql -u vivek -p -e 'SELECT COUNT(*) FROM quotes' cbzquotes
查询可能需要更长时间才能执行,但不应对其他进程产生负面影响。