Mysql 查询速度非常慢,以较大的限制范围排序
MySQL 5.6,64位,RHEL 5.8Mysql 查询速度非常慢,以较大的限制范围排序,mysql,sql,performance,optimization,Mysql,Sql,Performance,Optimization,MySQL 5.6,64位,RHEL 5.8 对具有ORDER BY和LIMIT“row\U count”(或LIMIT 0,“row\U count”)的大型表的查询。如果“行计数”大于结果集的实际计数,则速度将非常慢。 案例1:下面的查询非常快(没有“限制”): 表定义: CREATE TABLE syslog ( id BIGINT NOT NULL AUTO_INCREMENT, ReceivedAt TIMESTAMP NOT NULL DEFAUL
对具有ORDER BY和LIMIT“row\U count”(或LIMIT 0,“row\U count”)的大型表的查询。如果“行计数”大于结果集的实际计数,则速度将非常慢。
案例1:下面的查询非常快(没有“限制”): 表定义:
CREATE TABLE syslog (
id BIGINT NOT NULL AUTO_INCREMENT,
ReceivedAt TIMESTAMP NOT NULL DEFAULT 0,
ReportedTime TIMESTAMP NOT NULL DEFAULT 0,
Priority SMALLINT,
Facility SMALLINT,
FromHost VARCHAR(60),
Message TEXT,
InfoUnitID INT NOT NULL DEFAULT 0,
SysLogTag VARCHAR(60) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY idx_ReportedTime_Priority_id (ReportedTime,Priority,id),
KEY idx_Facility (Facility),
KEY idx_SysLogTag (SysLogTag(16)),
KEY idx_FromHost (FromHost(16))
);
Mysql以其围绕
orderbydesc+LIMIT
子句的行为而闻名
见:
请尝试:
SELECT *
FROM syslog FORCE INDEX (Facility)
WHERE
ReportedTime BETWEEN '2013-11-04' AND '2013-11-05'
AND Priority<3
AND Facility=1
ORDER BY id DESC
LIMIT 7;
选择*
来自syslog FORCE INDEX(设施)
哪里
报告时间介于“2013-11-04”和“2013-11-05”之间
首先,你是否也尝试过在设施上建立索引?这是InnoDB还是MyISAM,甚至是Archive之类的东西?向我们展示查询的解释计划,这会占用更多的时间。这里的主要问题是,如果索引会影响查询,第一种和第二种情况也会变慢。正确的?极限6(快速)和极限7(非常慢)之间的巨大性能差异。解释说它只使用了主键。我在InnoDB和MyISAM中都尝试过。遇到同样的问题。我添加了强制索引(idx\u ReportedTime\u Priority\u id)
。它很快就会恢复正常。我不知道MySQL的内部结构,为什么从limit5
到limit6
会有如此大的不同。非常感谢你。
mysql> SELECT * FROM syslog WHERE
(ReportedTime BETWEEN '2013-11-04' AND '2013-11-05') AND
Priority<3 AND Facility=1 ORDER BY id DESC LIMIT 7;
+---
| ...
6 rows in set (28 min 7.24 sec)
-+-----..-+----..+-------+-----..+--------+---------+-----+-----+------------+
| sele.. | table| type | poss..| key | key_len | ref | rows| Extra |
-+-----..-+----..+-------+-----..+--------+---------+-----+-----+------------+
| SIMPLE | syslo| index | ... | PRIMARY| 8 | NULL| 132 | Using where|
-+-----..-+----..+-------+-----..+--------+---------+-----+-----+------------+
1 row in set (0.00 sec)
CREATE TABLE syslog (
id BIGINT NOT NULL AUTO_INCREMENT,
ReceivedAt TIMESTAMP NOT NULL DEFAULT 0,
ReportedTime TIMESTAMP NOT NULL DEFAULT 0,
Priority SMALLINT,
Facility SMALLINT,
FromHost VARCHAR(60),
Message TEXT,
InfoUnitID INT NOT NULL DEFAULT 0,
SysLogTag VARCHAR(60) NOT NULL DEFAULT '',
PRIMARY KEY (id),
KEY idx_ReportedTime_Priority_id (ReportedTime,Priority,id),
KEY idx_Facility (Facility),
KEY idx_SysLogTag (SysLogTag(16)),
KEY idx_FromHost (FromHost(16))
);
SELECT *
FROM syslog FORCE INDEX (Facility)
WHERE
ReportedTime BETWEEN '2013-11-04' AND '2013-11-05'
AND Priority<3
AND Facility=1
ORDER BY id DESC
LIMIT 7;