[英]Why would an indexed column return results slowly when querying for `IS NULL`?
我有一個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;
本地開發立即顯示結果(<200ms)。 生產服務器大幅減速(40-70秒!)。
你能指出我正確的調試方向嗎?
說明:
+----+-------------+--------+-------------+-----------------------+-----------------+---------+------+-------+--------------------------------------------------------+
| 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 |
+----+-------------+--------+-------------+-----------------------+-----------------+---------+------+-------+--------------------------------------------------------+
SELECT
語句每個表只能使用一個索引。
據推測,之前的查詢僅使用條件class_id=1
的唯一索引class_id
進行掃描。 在檢查其他條件之前,這可能會很好地過濾您的結果集。
優化器“錯誤地”在class_id
上選擇索引合並,為第二個查詢選擇status
,並檢查可能不是最佳的26811行。 您可以通過在FROM
子句的末尾添加USING INDEX (class_id)
來提示class_id
索引。 您可以通過(class_id,status,grade)
上的復合索引獲得一些樂趣,它可以更快地運行查詢,因為它可以匹配前兩個,然后范圍掃描grade
。 我不確定這是如何使用null
。
我猜測ORDER BY
推動優化器再次選擇class_id
索引並將查詢返回到原始速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.