Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是什么让这个查询变得如此缓慢?(MySQL 5.6.36)_Mysql_Sql_Cpu_Mysql Slow Query Log - Fatal编程技术网

是什么让这个查询变得如此缓慢?(MySQL 5.6.36)

是什么让这个查询变得如此缓慢?(MySQL 5.6.36),mysql,sql,cpu,mysql-slow-query-log,Mysql,Sql,Cpu,Mysql Slow Query Log,我有一个不断增加的约800万行的数据库表,我的应用程序定期从中获取数据。但是,查询突然开始锁定整个系统。有大量的mysqld进程阻塞了所有CPU核心 可能是因为数据库的规模越来越大吗?或者,下面的查询中是否存在可能导致其运行这么长时间的内容?例如,UNIX\u时间戳?这是慢速查询日志的摘录。查询每分钟执行一次,查询时间始终在~7左右 # Query_time: 6.839524 Lock_time: 0.000170 Rows_sent: 277 Rows_examined: 7989334

我有一个不断增加的约800万行的数据库表,我的应用程序定期从中获取数据。但是,查询突然开始锁定整个系统。有大量的
mysqld
进程阻塞了所有CPU核心

可能是因为数据库的规模越来越大吗?或者,下面的查询中是否存在可能导致其运行这么长时间的内容?例如,
UNIX\u时间戳
?这是慢速查询日志的摘录。查询每分钟执行一次,查询时间始终在~7左右

# Query_time: 6.839524  Lock_time: 0.000170 Rows_sent: 277  Rows_examined: 7989334
FROM (
    SELECT @row := @row + 1 AS `row`, `timestamp`, `price`
    FROM (
        SELECT @row := 0
    ) `derived_1`, `items`
    WHERE `price` IS NOT NULL
        AND `timestamp` >= UNIX_TIMESTAMP(NOW() - INTERVAL 1 DAY)
        AND `currency` = 'EUR'
        AND `type` = 'icon'
    ORDER BY `timestamp` ASC
) `derived_2`
WHERE `row` % 8 = 0;
只是尝试一下有点困难,因为这是一个生产环境。我也不能在我的开发环境中重现这个问题

如果您需要任何其他信息,请让我知道


提前多谢

时间戳上的索引应该会带来更好的性能。特别是,因为时间戳列的值可能分布良好。关于货币和类型的索引可能会带来另一个性能提升。但也许您甚至没有注意到,因为只有几种不同的货币和数据类型(与800万行相比)

是的,这需要一些时间


UNIX\u时间戳(NOW()-INTERVAL 1 DAY)不是问题,因为它只计算一次。

创建一个索引,以便DBMS可以快速找到记录。此索引应包含
WHERE
子句的列,从与
=
比较的列开始

CREATE idx ON items (type, currency, price, timestamp);

这甚至碰巧是一个覆盖索引,即它包含您在查询中使用的所有列。因此,DBMS甚至不必读取表,因为它可以从索引本身获取所有数据。

最好的索引是:

INDEX(type, currency,  -- The two columns tested via '=' (in either order)
      timestamp,       -- then this, for a range test
      price)           -- finally, the rest of the columns used
这将是一个“覆盖”索引,因此它不必在索引BTree和数据BTree之间反弹。(其他建议的索引将因此而变慢。)

希望这将使查询的运行速度超过7秒

“每分钟”运行一些东西是不安全的。无论出于何种原因,如果一个实例无法在一分钟内完成,会发生什么?多个调用可能会相互绊倒,并且可能会变得越来越慢。这可能已经阻碍了你的经验


为了避免这种情况,让作业持续运行——计算查询,然后休眠,比如说53秒。这将(基于当前的计时)非常接近每分钟一次。或者它可以暂停到下一分钟(但不少于0秒)。

您是否在where子句中的字段上有索引,或者表的索引是什么?请发布
EXPLAIN
的输出。您是否可以共享要查看的执行计划。它是在执行查询时生成的,这显示了数据传输。@Thierry这不太好,如果where子句中的字段没有索引,DB引擎必须扫描表中的所有条目,显然也是为了排序。因此,行数越多,速度就越慢。非常感谢!我一定会试试的。出于好奇:为什么只有
时间戳
对索引有用,而不是
货币
类型
?这与它们的不变性有关吗?同样,对这样大小的表进行索引是否会导致插入/更新/。。。排?我应该为这样的停工负责吗?@Thierry:别担心。是的,插入、更新和删除需要更长的时间,但我想我们这里说的是微秒。大规模更新通常是不必要的,大规模插入通常不会发生,因此可能只会发生大规模删除,并遭受一些损失,但这是付出的代价:-)@Thierry:我收集了一些链接,我发现这些问题对我很有帮助:谢谢大家,@nCessity!这是我最喜欢的答案!一开始我没有想到要覆盖索引@谢谢。不过,你关于选择性的评论也是正确的。因此,可能值得尝试两个覆盖索引,一个以时间戳开始,一个不以时间戳开始,然后查看DBMS选择哪个索引。
INDEX(type, currency,  -- The two columns tested via '=' (in either order)
      timestamp,       -- then this, for a range test
      price)           -- finally, the rest of the columns used