[英]MySQL -Improve slow query performance
Iam running my Rails application with MySQL. 我用MySQL运行我的Rails应用程序。 I started reviewing my MySQL slow query log and I saw there were around 6000 lines which has mostly repeated the following query.
我开始查看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
System Events Table 系统事件表
System Events Explain: 系统事件说明:
Does select count(*) have performance issues? 选择计数(*)是否存在性能问题? How to resolve them?
如何解决?
The issue is that you only have single column indexes, while the where
criteria would be served by a multi-column index. 问题是您只有单列索引,而
where
条件将由多列索引提供。 MySQL tries to make up for by using index merge, but that is not as efficient as using a single index. MySQL尝试通过使用索引合并来弥补这一点,但是效率不如使用单个索引。
I would create a multi-column index on customer_id
, classification
, and created_at
fields and I would also move the notified
field back of the where criteria (it should be the last condition. 我想创建一个多列索引
customer_id
, classification
和created_at
领域,我也动notified
现场发回的地方标准(应该是最后一个条件。
Based on how you use the notified
field, it seems to be a Boolean field with 0 or 1 value. 根据您使用
notified
字段的方式,它似乎是一个布尔值字段,值为0或1。 Therefore adding it to an index will not really increase the selectivity of the index. 因此,将其添加到索引不会真正增加索引的选择性。
INDEX(notified, customer_id, classification, created_at)
created_at
needs to be last; created_at
必须是最后一个; the rest can be in any order. 其余的可以是任何顺序。
notified
requires looking at more rows, and having to skip over any with the wrong value for that column. notified
要求查看更多行,并且必须跳过该列具有错误值的任何行。 (Hence, I disagree with @Shadow on whether to include notified
.) notified
。) Without seeing SHOW CREATE TABLE
, I cannot say whether the following "covering" index might be better, or whether it implicitly exists: 如果没有看到
SHOW CREATE TABLE
,就不能说以下“覆盖”索引是否会更好,或者它是否隐含地存在:
INDEX(notified, customer_id, classification, created_at, id) INDEX(已通知,customer_id,分类,created_at,id)
If you are not expecting 2 billion customers, consider using something smaller than a 4-byte INT
. 如果您不希望有20亿客户,请考虑使用小于4字节
INT
。 A 2-byte SMALLINT UNSIGNED
allows up to 64K ids. 2字节的
SMALLINT UNSIGNED
最多允许64K ID。 (Ditto for other INTs
.) (与其他
INTs
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.