我用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
系统事件表
系统事件说明:
select count(*)是否存在性能问题?如何解决?
答案 0 :(得分:1)
问题是您只有单列索引,而where
条件将由多列索引提供。 MySQL试图通过使用索引合并来弥补,但这不如使用单个索引那么有效。
我会在customer_id
,classification
和created_at
字段上创建一个多列索引,我还会将notified
字段移回where标准(它应该是最后一个条件。
根据您使用notified
字段的方式,它似乎是一个0或1值的布尔字段。因此,将其添加到索引中并不会真正提高索引的选择性。
答案 1 :(得分:0)
INDEX(notified, customer_id, classification, created_at)
created_at
需要持久;其余的可以是任何顺序。
notified
需要查看更多行,并且必须跳过具有该列错误值的任何行。 (因此,我不同意@Shadow是否包括notified
。)在没有看到SHOW CREATE TABLE
的情况下,我不能说以下是否"覆盖" index可能更好,或者是否隐含存在:
INDEX(通知,customer_id,分类,created_at,id)
如果您不期望20亿客户,请考虑使用小于4字节INT
的内容。 2字节SMALLINT UNSIGNED
允许最多64K ID。 (同上其他INTs
。)