简体   繁体   English

MySQL查询有时运行缓慢,有时运行很快

[英]MySQL query sometimes run slow, sometimes fast

I am having problem with this simple MySQL query: 我在使用此简单的MySQL查询时遇到问题:

select sender as id from message where status=1 and recipient=1

where sender table has multi millions of rows. 其中发件人表具有数百万行。

When I run this on SequelPro, it runs really slow for the first time, ~4 seconds or more, and the next execution it run really fast, ~0.018 seconds. 当我在SequelPro上运行此程序时,它第一次运行速度非常慢,大约4秒或更长,而下一次执行时,它运行速度非常快,大约0.018秒。 However, if I run again after couple of minutes, it will do the same thing again. 但是,如果几分钟后再次运行,它将再次执行相同的操作。

I tried to use SQL_NO_CACHE, and it still gives me the same result. 我尝试使用SQL_NO_CACHE,它仍然给我相同的结果。

The DB engine is innoDB, and the DB is MySQL Percona XtraDB cluster. 数据库引擎是innoDB,数据库是MySQL Percona XtraDB集群。 Here is the explain results: 这是解释结果:

|id|select_type|table  |type|possible_keys         |key |key_len|ref            |row   |Extra
| 1|SIMPLE     |message|ref |recipient,status, sent|sent|12     |const,const    |2989   |NULL

"sent" is an index of multi-column of (recipient, status). “已发送”是(收件人,状态)的多列索引。 Does anyone has any idea to fix this problem? 有谁有解决这个问题的想法?

Thank you. 谢谢。

Added (from comment) 已添加 (来自评论)

CREATE TABLE 'message' (
    'id' int(20) NOT NULL AUTO_INCREMENT, 
    'sender' bigint(20) NOT NULL, 
    'recipient' bigint(20) NOT NULL, 
    'status' int(5) NOT NULL, 
    'date' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY ('id'), 
    KEY 'id' ('id'), 
    KEY 'recipient' ('recipient'), 
    KEY 'sender' ('sender'), 
    KEY 'date' ('date'), 
    KEY 'status' ('status'), 
    KEY 'sent' ('status','recipient')
) ENGINE=InnoDB AUTO_INCREMENT=90224500 DEFAULT CHARSET=latin1;

Those symptoms point to caching issues. 这些症状指向缓存问题。 I don't mean the "Query cache", but rather the Engine's cache. 我不是说“查询缓存”,而是引擎的缓存。

How big is the table? 桌子多大? How big are all the the active tables? 所有活动表有多大?

What is the value of innodb_buffer_pool_size ? innodb_buffer_pool_size的值是innodb_buffer_pool_size

I suspect the buffer_pool is a lot smaller than the table(s), and a lot of stuff is going on. 我怀疑buffer_pool比表小很多,并且发生了很多事情。 Hence, the query's blocks get bumped out of RAM, necessitating a few dozen reads to bring them back in. 因此,查询的块会从RAM中移出,需要进行几十次读取才能将它们带回。

innodb_buffer_pool_size should be set to about 70% of available RAM. innodb_buffer_pool_size设置为可用RAM的大约70%。

More (based on CREATE TABLE ) 更多 (基于CREATE TABLE

The "covering" INDEX(status, recipient, sender) will be faster -- it won't have to bounce over to the data; “覆盖”的INDEX(status, recipient, sender)将更快-无需跳回数据; the query can be done entirely in the index. 查询可以完全在索引中完成。

A PRIMARY KEY is a key, so INDEX(id) is redundant and can be DROPped . PRIMARY KEY是密钥,因此INDEX(id)是冗余的,可以被DROPped

A KEY that is a prefix of another key is redundant. 作为另一个键的前缀的KEY是多余的。 I am referring to (status) in your current CREATE TABLE . 我指的是您当前的CREATE TABLE (status)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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