[英]Why does it contain “Using where”?
這是我的表架構。
CREATE TABLE `usr_block_phone` (
`usr_block_phone_uid` BIGINT (20) UNSIGNED NOT NULL AUTO_INCREMENT,
`time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`usr_uid` INT (10) UNSIGNED NOT NULL,
`block_phone` VARCHAR (20) NOT NULL,
`status` INT (4) NOT NULL,
PRIMARY KEY (`usr_block_phone_uid`),
KEY `block_phone` (`block_phone`),
KEY `usr_uid_block_phone` (`usr_uid`, `block_phone`) USING BTREE,
KEY `usr_uid` (`usr_uid`) USING BTREE
) ENGINE = INNODB DEFAULT CHARSET = utf8
這是我的SQL
SELECT
ubp.usr_block_phone_uid
FROM
usr_block_phone ubp
WHERE
ubp.usr_uid = 19
AND ubp.block_phone = '80000000001'
順便說一句,當我運行“ EXPLAIN”時,得到的結果如下。
+------+-------------+-------+------+-----------------------------------------+---------------------+---------+-------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+-----------------------------------------+---------------------+---------+-------------+------+--------------------------+
| 1 | SIMPLE | ubp | ref | block_phone,usr_uid_block_phone,usr_uid | usr_uid_block_phone | 66 | const,const | 1 | Using where; Using index |
+------+-------------+-------+------+-----------------------------------------+---------------------+---------+-------------+------+--------------------------+
為什么索引usr_uid_block_phone
不起作用? 我只想using index
。
該表現在有20000行。
您的索引已被實際使用,請參見key
列。 目前,查詢看起來不錯,執行計划也不錯。
至少要填充一百以供使用(並確保您仍然使用僅過濾一行的謂詞)。
還有一個一般性建議:除非您自己是mysql dbms開發人員,否則要預測優化器在特定情況下的行為幾乎是不可能的。 因此,總是最好嘗試一個盡可能接近生產的數據集(就數據的大小和質量而言)。
WHERE
子句中使用的兩列( usr_uid
和block_phone
)都存在於usr_uid_block_phone
索引中,這使它成為可能用於處理查詢的鍵。 更重要的是,它是選擇的索引,但是由於表中的行數較少,MySQL決定不使用索引更快。
原因在於SELECT
子句中存在的表達式:
SELECT
ubp.usr_block_phone_uid
因為所選索引中不存在usr_block_phone_uid
列,所以為了處理查詢,MySQL需要讀取索引(以確定哪些行與WHERE
條件匹配) 和表數據(獲取這些行的usr_block_phone_uid
列的值) )。
僅讀取表數據並使用WHERE
條件查找匹配的行並獲取其usr_block_phone_uid
列會usr_block_phone_uid
。 它需要從一個位置讀取存儲中的數據。 如果使用索引,則需要讀取相同的數據和索引數據。
當表增長時,情況(以及EXPLAIN
的報告)會發生變化。 在某些時候,從索引中讀取信息(並使用它來過濾出行)會被大量被過濾掉的行(即,不從存儲中讀取其數據)所補償。
發生這種情況的確切時間並不確定。 這取決於表的許多結構以及表中的值如何散布。 即使表很大,MySQL仍可以決定忽略索引,以便從存儲介質中讀取較少的信息。 例如,如果大部分表行(假設90%)與WHERE
條件匹配,則讀取所有表數據(忽略索引)比讀取90%的表數據和90%的表數據更有效。索引。
上段中90%是我為解釋目的而編造的數字。 我不知道MySQL如何決定最好忽略索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.