长时间运行不重要的查询会减慢其他查询的速度

时间:2014-09-25 11:21:37

标签: mysql sql

我有一个cronjob,每5分钟执行一次长时间运行的查询。此查询不是时间关键,目前大约需要30秒才能完成。

问题在于,在执行查询时,所有其他查询的运行速度都要慢得多。

查询非常简单(没有连接,使用索引等)但是读取了大量数据(1.5 mil行,每行约150个字节的数据)。

我无法轻松缓存结果,因为所有数据都可以随时更改。

有没有办法限制这个特定的查询?

修改 查询真的只是:

SELECT field1,field2 FROM table;

编辑2: 好的,很抱歉这样说,但是你们每个人都错过了这一点。我问我是否可以限制查询,我得到的所有答案都没有解决问题。你们都告诉我改变cronjob(我知道我可以),从cli运行它(我不想),以块的形式获取数据等。

我再次具体要求我可以以某种方式执行MySQL SELECT查询“不重要”,这样它就不会从其他查询中窃取所有资源吗?

对不起,如果这听起来像是一个主要的咆哮,我很感谢你花时间来帮助:)

4 个答案:

答案 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

查询可能需要更长时间才能执行,但不应对其他进程产生负面影响。