Mysql

WHERE 列中沒有使用索引警告為空

  • November 20, 2021

我收到這個警告:

查詢/準備語句中未使用索引 SELECT * FROM mTab​​le WHERE my_column IS NULL

但是my_column已經被索引了。

MariaDB [mytest]> SHOW INDEX FROM mTable;
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table  | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| mTable |          0 | PRIMARY   |            1 | id          | A         |          11 |     NULL | NULL   |      | BTREE      |         |               |
| mTable |          1 | my_column |            1 | my_column   | A         |          11 |     NULL | NULL   | YES  | BTREE      |         |               |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

原因可能my_column實際上包含NULL值,所以實際上沒有索引,這就是 MySQL 抱怨的原因?但隨後我必須查詢NULL.

有什麼想法可以更好地解決這個問題嗎?

這就是為什麼您應該對“未使用索引”警告持保留態度的原因。

當您說其中之一時INDEX(col)

WHERE col IS NULL
WHERE col = 123

並且測試超過表中大約20% 的行為真,優化器將避開索引並簡單地掃描表。

為什麼?使用索引時,在掃描索引和查找數據中的行之間存在來回操作。那是兩個獨立的 BTree。優化器會猜測來回執行是否會比簡單地掃描所有行、扔掉那些未通過測試的行更快。

截止值通常在 20% 左右,但我看到的範圍在 10% 到 30% 之間。

無論如何,您都應該創建和索引。

執行以下查詢:

SELECT COUNT(1) rowcount,my_column FROM mTable GROUP BY my_column
UNION SELECT COUNT(1) rowcount,'Whole Table' FROM mTable;
SELECT DISTINCT my_column 'Cardinality' from mTable;

如果 for 的行數NULL超過 的 5% ,則如果您的子句是or (特別是如果具有的行數與具有非的行數大致相同),則Whole Table可能不會將索引用作查詢優化器。如果 的基數非常低(表示唯一值的數量很少),則可能根本不會使用索引。WHERE``AND my_column IS NULL``AND my_column IS NOT NULL``NULL``NULL``my_column``my_column

如果您在 上創建索引,您提到的警告可能會消失my_column,但如果我提到的情況適用,則可能永遠不會使用該索引。

NULL如果my_column 佔表的 90%,則該索引可能是有價值的。

我的建議是暫時不要製作。

引用自:https://dba.stackexchange.com/questions/241219