简体   繁体   English

MySQL-改善慢查询性能

[英]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_idclassificationcreated_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. 其余的可以是任何顺序。

  • With all 4 columns only the relevant number of rows will be touched. 对于所有4列,仅会触摸相关的行数。
  • Leaving out 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 .) (因此,我不同意关于是否包括@Shadow notified 。)
  • The existing indexes did an "index merge intersect" of two columns, which is probably always slower than having a composite index. 现有索引执行了两列的“索引合并相交”,这可能总是比使用复合索引慢。
  • 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM