【发布时间】:2014-10-07 09:33:36
【问题描述】:
我有一个包含 2500 万行的表,并有适当的索引。
但是添加子句AND status IS NULL 会将超快查询变成疯狂的慢查询。
请帮我加快速度。
查询:
SELECT
student_id,
grade,
status
FROM
grades
WHERE
class_id = 1
AND status IS NULL -- This line delays results from <200ms to 40-70s!
AND grade BETWEEN 0 AND 0.7
LIMIT 25;
表:
CREATE TABLE IF NOT EXISTS `grades` (
`student_id` BIGINT(20) NOT NULL,
`class_id` INT(11) NOT NULL,
`grade` FLOAT(10,6) DEFAULT NULL,
`status` INT(11) DEFAULT NULL,
UNIQUE KEY `unique_key` (`student_id`,`class_id`),
KEY `class_id` (`class_id`),
KEY `status` (`status`),
KEY `grade` (`grade`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
本地开发会立即显示结果(
你能指出正确的调试方向吗?
解释:
+----+-------------+--------+-------------+-----------------------+-----------------+---------+------+-------+--------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------------+-----------------------+-----------------+---------+------+-------+--------------------------------------------------------+
| 1 | SIMPLE | grades | index_merge | class_id,status,grade | status,class_id | 5,4 | NULL | 26811 | Using intersect(status,class_id); Using where |
+----+-------------+--------+-------------+-----------------------+-----------------+---------+------+-------+--------------------------------------------------------+
【问题讨论】:
-
explain select ...输出什么? -
@juergend 在上面添加了解释。
-
请注意,没有 ORDER BY 的 LIMIT 几乎没有意义
-
并将 FLOAT 更改为 DECIMAL
-
ORDER BY加快查询备份的事实,虽然本身是一个很好的建议,但并不是问题的答案.. 不要依赖它来加速将来的类似查询.
标签: mysql sql optimization null query-optimization