【发布时间】:2016-03-11 04:17:34
【问题描述】:
我对这个简单的 MySQL 查询有疑问:
select sender as id from message where status=1 and recipient=1
其中发件人表有数百万行。
当我在 SequelPro 上运行它时,它第一次运行很慢,大约 4 秒或更长时间,而下一次运行它运行得非常快,大约 0.018 秒。但是,如果我在几分钟后再次运行,它会再次执行相同的操作。
我尝试使用 SQL_NO_CACHE,但结果仍然相同。
数据库引擎为innoDB,数据库为MySQL Percona XtraDB集群。 解释结果如下:
|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”是(recipient,status)多列的索引。 有没有人有解决这个问题的想法?
谢谢。
添加(来自评论)
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;
【问题讨论】:
-
您可以在 mysql 查询中使用限制。例如
select sender as id from message where status=1 and recipient=1 LIMIT 10或者你也可以使用select sender as id from message where status=1 and recipient=1 LIMIT 10 OFFSET 15等偏移量 -
@SanjayChaudhari 感谢您的回复。但是,我想从表中获取所有结果。这就是我不使用 LIMIT 的原因。但我会尝试每 100 条记录循环一次查询,看看它是否有什么不同,即使这不是一个好的解决方案,因为将来记录会增长。
-
看看你的索引是否使用得当。此外,备份表并重新创建它。然后从转储中导入记录一次。分散的记录可能会聚集在一起并稍微提高性能。
标签: php mysql innodb percona xtradb