2011-10-18 104 views
2

我需要此幫助。我有這樣的查詢:使用帶範圍類型查詢和其他標準的索引

SELECT * FROM cart WHERE 
(ts_in between 1249077600 AND 1318975199); 

以上查詢使用ts_in colomn(範圍類型)上的btree索引。現在我想添加另一個標準。例如:

SELECT * FROM cart WHERE 
(ts_in between 1249077600 AND 1318975199) and is_removed=0; 

上述查詢不使用ts_in colomn(範圍)上的btree索引。

有人可以告訴我爲什麼以及如何正確實現快速計算。

我創建了測試兩個指標:

CREATE INDEX range_idx_1 using BTREE 
ON cart (is_removed, ts_in); 

CREATE INDEX range_idx_2 using BTREE 
ON cart (ts_in , is_removed); 

有什麼好笑的是,當我使用這個查詢:

EXPLAIN SELECT id FROM cart WHERE 
(ts_in between 1249077600 AND 1318975199) AND is_removed=0; 

我收到這樣的結果:

id | select_type | table | type | possible_keys   | key   | key_len | ref | rows | Extra 
1 | SIMPLE  | cart | range | range_idx_1,range_idx_2 | range_idx_1 | 6  |  | 17391 | Using where; Using index 

上述查詢使用索引但:

EXPLAIN SELECT * FROM cart WHERE 
(ts_in between 1249077600 AND 1318975199) AND is_removed=0; 

我有這樣的結果:

id | select_type | table | type | possible_keys   | key   | key_len | ref | rows | Extra 
1 | SIMPLE  | cart | ref | range_idx_1,range_idx_2 | range_idx_1 | 1  | const | 77979 | Using where 

這不使用索引。

當我嘗試使用INDEX或FORCE INDEX語法時,結果是相同的。在一種情況下,Mysql不使用索引。任何幫助?

+0

請發佈每個查詢的解釋計劃。 – Hammerite

+0

它是MyISAM還是InnoDB表?我猜這是InnoDB? –

+0

我爲以上每個場景添加了執行計劃。看起來第二個查詢不是類型範圍,但爲什麼? –

回答

1

運行

EXPLAIN SELECT * FROM cart WHERE 
(ts_in between 1249077600 AND 1318975199) and is_removed=0; 

明白爲什麼MySQL查詢優化器選擇不同的索引。

Mysql並不擅長組合索引本身,因此您可能需要此查詢的組合索引。嘗試爲is_removed, ts_in添加索引(btree?)(按此順序!)。

您還可以強制mysql通過向查詢添加USE INDEX來使用您的索引。有時候這會給查詢優化器選擇的索引帶來更好的結果:

SELECT * FROM cart USE INDEX '<idx_name>' WHERE 
(ts_in between 1249077600 AND 1318975199) and is_removed=0; 
+0

我用更多的信息填充問題。 USE INDEX或FORCE INDEX沒有用。當我在這個查詢中「select *」時,mysql不使用索引。當我有「選擇id」例如然後mysql正在使用正確的索引,但我需要解決方案「select *」。 –

+0

在索引中存儲'id'(我假設id是主鍵),所以mysql不需要訪問表本身來生成結果集。但是對於select *它需要,並且查詢優化器使用索引得出結論在這種情況下沒有任何意義。對於'*',我認爲你會以最簡單的方式做到這一點。也許某種級聯查詢可以工作...... – HefferWolf