Mysql
WHERE 列中沒有使用索引警告為空
我收到這個警告:
查詢/準備語句中未使用索引 SELECT * FROM mTable 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%,則該索引可能是有價值的。我的建議是暫時不要製作。