2012-12-11 22 views
0

我已經檢查了許多其他SO帖子和MySQL文檔,但似乎無法得到答案,爲什麼沒有使用索引,以及如何強制它被使用 - 我可以看到許多其他人都有類似的問題,但找不到解決方案。爲什麼MySQL在範圍查詢中不使用組合鍵?

的表看起來像這樣

CREATE TABLE `countries_ip` (
`ipfrom` INT(10) UNSIGNED ZEROFILL NOT NULL, 
`ipto` INT(10) UNSIGNED ZEROFILL NOT NULL, 
`countrySHORT` CHAR(2) NULL DEFAULT NULL, 
`country_id` INT(10) UNSIGNED NOT NULL, 
PRIMARY KEY (`ipfrom`, `ipto`, `country_id`), 
INDEX `from_to_index` (`ipfrom`, `ipto`) 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

不知道爲什麼「from_to_index」是存在的 - 似乎是多餘的給我。但無論如何,EXPLAIN的查詢看起來像這樣

EXPLAIN SELECT * 
     FROM track_report t, countries_ip ip 
     WHERE t.ip BETWEEN ip.ipfrom AND ip.ipto 

和的解釋結果如下:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE t ALL getwebmaster NULL NULL NULL 36291 
1 SIMPLE ip ALL PRIMARY,from_to_index NULL NULL NULL 153914 Range checked for each record (index map: 0x3) 

正如你所看到的,在不使用從countries_ip表的主鍵所以查詢需要一個很長的時間(countries_ip有超過150k記錄)

我可能會錯過簡單的東西,但任何意見將不勝感激我如何可以優化此查詢。提前致謝。

+0

您是否嘗試過使用顯式連接? –

+0

連接條件是範圍綁定的,這會導致全表掃描,您可以使用邏輯運算符代替 –

+0

@juergen - 很遺憾,使用INNER JOIN並沒有什麼區別,並且Sashi不幸使用邏輯操作符! – pavsid

回答

1

可能幫助定義在track_report.ip上的索引。見SQL Fiddle

我修改了where子句來做一個明確的比較,現在它使用from_to_index。

SELECT ip 
FROM track_report t, countries_ip ip 
where t.ip >= ip.ipfrom and t.ip <= ip.ipto 

參見SQL Fiddle

+0

您好奧拉夫,已經有一個索引'track_report' - 'getwebmaster'是一個複合關鍵,其中'ip'是第一個字段 – pavsid

+0

@pavsid根據你的解釋它不被使用,而在SQL小提琴它使用單列索引,我定義。 –

+0

的確如此,但這可能歸結於我的EXPLAIN中的優化器。即使我專門爲'ip'字段添加一個索引,那麼索引不會被使用(可能是由於表的大小?) – pavsid