2013-10-02 46 views
3

我有一個測試表(table1),其中有6條記錄。我想根據列(col1)獲取多個數據的數據。 所以我索引列。現在,如果我在IN子句中選擇帶有強制索引的所有列(*)中的多個值,我會得到特定記錄而不是全表掃描。如果我運行與選定的列相同的查詢,我發現它執行全表掃描。Mysql IN子句全表掃描

我已經讀過使用select select(*)在select查詢中不好。但是,如果我不使用全選(*),則會有全表掃描。 我無法理解mysql如何讀取查詢。請幫我解決這個問題。

+----+--------+---------+ 
| id | col1 | col2 | 
+----+--------+---------+ 
| 1 | 100000 | E100000 | 
| 2 | 100001 | E200001 | 
| 3 | 100002 | E300002 | 
| 4 | 100003 | E400003 | 
| 5 | 100004 | E500004 | 
| 6 | 100005 | E600005 | 
+----+--------+---------+ 

INDEX

+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| table1 |   0 | PRIMARY |   1 | id   | A   |   6 |  NULL | NULL |  | BTREE  |   |    | 
| table1 |   1 | col1  |   1 | col1  | A   |   6 |  NULL | NULL |  | BTREE  |   |    | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 

EXPLAIN(使用武力INDEX(COL1),然後選擇所有(*)列)

select * from table1 force index(col1) where col1 in ('100000', '100001'); 

+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+ 
| 1 | SIMPLE  | table1 | range | col1   | col1 | 10  | NULL | 2 | Using where | 
+----+-------------+----------+-------+---------------+-------+---------+------+------+-------------+ 

EXPLAIN(使用FORCE INDEX(COL1)並僅選擇1個數據,而不是所有(*))

select col1 from table1 force index(col1) where col1 in ('100000', '100001'); 

+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra     | 
+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+ 
| 1 | SIMPLE  | table1 | range | col1   | col1 | 10  | NULL | 6 | Using where; Using index | 
+----+-------------+----------+-------+---------------+-------+---------+------+------+--------------------------+ 
+0

其實它比這更復雜,你的桌子很小,所以全面掃描是最好的:) – Gar

+0

@Gar:以上列表只是一張測試表,原表中將有超過60,000條記錄 – sravis

+1

如果需要的記錄數量佔可用記錄數量的相當大的百分比,MySQL往往不會對索引產生影響。添加幾十個測試記錄,我懷疑結果會改變。 – Kickstart

回答

1
  1. MySQL優化看到該表是太小和全掃描會 更有效首先搜索索引並稍後檢索數據。
  2. 當您只選擇一列時,MySQL優化器會發現,此 列位於索引中,並且沒有必要從 檢索數據 - 讀取索引就足夠了。

優化器如何確定哪些更有效? 它試圖預測磁盤讀取塊操作的數量。

正如之前在評論中提到的,在大表中EXPLAIN會有所不同。