【发布时间】:2015-07-16 09:33:39
【问题描述】:
我们使用的是 MySQL 5.5.42。
我们有一个表 publications 包含大约 1.5 亿行(SSD 上大约 140 GB)。
该表有很多列,其中两列特别有趣:
-
id是表的主键,类型为bigint -
cluster_id是bigint类型的可空列
两列都有自己的(单独的)索引。
我们查询表单
SELECT * FROM publications
WHERE id >= 14032924480302800156 AND cluster_id IS NULL
ORDER BY id
LIMIT 0, 200;
问题出在这里:
id值越大(上例中为 14032924480302800156),请求越慢。
换句话说,低id 值的请求很快(id 值越高,请求越慢(最多几分钟)。
如果我们在WHERE 子句中使用另一个(索引)列,一切都很好。比如
SELECT * FROM publications
WHERE inserted_at >= '2014-06-20 19:30:25' AND cluster_id IS NULL
ORDER BY inserted_at
LIMIT 0, 200;
其中inserted_at 的类型为timestamp。
编辑:
使用id >= 14032924480302800156时EXPLAIN的输出:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---+-------------+--------------+------+--------------------+------------+---------+-------+----------+------------
1 | SIMPLE | publications | ref | PRIMARY,cluster_id | cluster_id | 9 | const | 71647796 | Using where
使用inserted_at >= '2014-06-20 19:30:25'时EXPLAIN的输出:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---+-------------+--------------+------+------------------------+------------+---------+-------+----------+------------
1 | SIMPLE | publications | ref | inserted_at,cluster_id | cluster_id | 9 | const | 71647796 | Using where
【问题讨论】:
-
也许对于更大的
ids,cluster_id匹配请求的值(NULL)更罕见?在这种情况下,对于较大的ids,数据库可能需要遍历更多记录,以便选择带有cluster_id IS NULL的请求的 200。 -
显示EXPLAIN 的输出,同时使用小ID和大ID。
-
@SergeRogatch 这是一个很好的评论,我们考虑过,但我很难相信这可以解释三个数量级的减速。
-
@ImreL 我编辑了问题,为两个查询添加了 EXPLAIN 的输出。
-
第一个请求中的using/forcing
PRIMARYindex 是否会极大地改变处理时间?如果是这样,我可能有一个理论......
标签: mysql performance