MySQL - 提高查询性能

时间:2017-03-06 09:41:22

标签: mysql performance

我用MySQL运行我的Rails应用程序。我开始查看我的MySQL慢查询日志,我看到大约有6000行,其中大部分重复了以下查询。

SET timestamp=1488423689;
SELECT COUNT(*) FROM `system_events`
    WHERE (notified
      AND id != 476200
      AND customer_id = 1
      AND classification = 50039
      AND created_at >= '2017-02-27 03:01:26');
# Time: 170302  3:01:49
# Thread_id: 2972915  Schema: ash####  Last_errno: 0  Killed: 0
# Query_time: 7.195183  Lock_time: 0.000029  Rows_sent: 1  Rows_examined: 26296  Rows_affected: 0  Rows_read: 26296
# Bytes_sent: 63

系统事件表

enter image description here

系统事件说明:

enter image description here

select count(*)是否存在性能问题?如何解决?

2 个答案:

答案 0 :(得分:1)

问题是您只有单列索引,而where条件将由多列索引提供。 MySQL试图通过使用索引合并来弥补,但这不如使用单个索引那么有效。

我会在customer_idclassificationcreated_at字段上创建一个多列索引,我还会将notified字段移回where标准(它应该是最后一个条件。

根据您使用notified字段的方式,它似乎是一个0或1值的布尔字段。因此,将其添加到索引中并不会真正提高索引的选择性。

答案 1 :(得分:0)

INDEX(notified, customer_id, classification, created_at)

created_at需要持久;其余的可以是任何顺序。

  • 只有所有4列都会触及相关的行数。
  • 退出notified需要查看更多行,并且必须跳过具有该列错误值的任何行。 (因此,我不同意@Shadow是否包括notified。)
  • 现有索引执行"索引合并相交"两列,可能总是慢于复合索引。
  • 在没有看到SHOW CREATE TABLE的情况下,我不能说以下是否"覆盖" index可能更好,或者是否隐含存在:

    INDEX(通知,customer_id,分类,created_at,id)

如果您不期望20亿客户,请考虑使用小于4字节INT的内容。 2字节SMALLINT UNSIGNED允许最多64K ID。 (同上其他INTs。)