2017-03-06 153 views
0

Iam使用MySQL运行我的Rails应用程序。我开始审查我的MySQL慢速查询日志,我看到大约有6000行主要重复以下查询。MySQL - 提高查询性能

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(*)有性能问题?如何解决它们?

回答

1

问题是您只有单列索引,而where标准将由多列索引提供。 MySQL试图通过使用索引合并来弥补,但这并不像使用单个索引那样高效。根据您如何使用

我将创建customer_idclassificationcreated_at领域一个多列索引,我也将移动notified现场发回的地方标准(应该是最后一个条件。

notified场,这似乎是一个0或1的值布尔字段因此将其添加到索引不会真正增加索引的选择性

0
INDEX(notified, customer_id, classification, created_at) 

created_at需求是最后的;其余的可在任何 订购。

  • 所有4列只有相关的行数会被触及。
  • 退出notified需要查看更多行,并且必须跳过该列中具有错误值的任何行。 (因此,我不同意@Shadow是否包含notified。)
  • 现有索引做了两列的“索引合并相交”,这可能是总是比具有组合索引慢。
  • 没有看到SHOW CREATE TABLE,我不能说下面的 “覆盖” 指标是否会得到更好的,还是含蓄地存在:

    INDEX(通知,CUSTOMER_ID,分类,created_at,ID)

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