2013-04-01 134 views
0

我對2個表運行查詢,並且由於某種原因它沒有使用索引。我無法想象我們爲了我的生活。查詢不使用索引

這裏是我的表格:table1table2。表1是154行的類別列表。表1的表格結構如下所示:

category_id (int11) - also has an index on it 
name (varchar30) - also has an index on it 
urltext (text) 
nametext (text) 

category_id  name urltext nametext 
1   category1 blahblah  blahblah 
2   category2 blahblah  blahblah 
3   category3 blahblah  blahblah 
4   category4 blahblah  blahblah 
etc to rows 
154   category154 blahblah  blahblah 

表2有100萬行,並且涉及產品類別。該表的字段結構如下:表2

row_id (bigint11) - also has an index 
category_id (int3) - also has an index 
product_id (int9) - also has an index 

的數據是這樣的:

row_id  category_id  product_id 
1    1   123456 
2    4   123456 
3    17   456789 
4    42   456789 
5    7   456789 
6    88   888555 

這裏是我的查詢:

select * 
from table2 
INNER JOIN table1 
ON table2.category_id=table1.category_id 
where table2.product_id = 123456; 

而現在,當我運行一個解釋在此查詢中:

id select_type table type possible_keys  key  key_len ref     rows Extra 
1 simple  table1 ALL PRIMARY   NULL  NULL  NULL     154 
1 simple  table2 ref product_id,... poduct_id 10  category_id, const 1  Using Where 

任何產品通常只涉及1到4個不同的類別。所以,你會認爲如果索引被正確使用,而不是在解釋結果中看到154行爲table1,你會看到最大爲4.

我最初將table1.name設置爲text而不是varchar(30),但結果仍然沒有改變。如果這是一個隨機使用的查詢,這並不重要,但是這個查詢每天的命中數以萬計。

我在做什麼錯在這裏,這個查詢沒有使用可用的索引來大量減少行數?

我希望我提供了正確的信息。提前致謝。

回答

1

你的查詢可以被重新格式化爲:

SELECT * 
FROM table2 
INNER JOIN table1 ON table2.category_id = table1.category_id 
WHERE table2.product_id = 123456 

要想快點,下列指標應該存在:

table1(category_id) 

通過table1.category_id快速進行查找。

而且

table2(category_id, product_id) 

table2(product_id, category_id) 

此多列(化合物)索引將致力於滿足這兩個條件JOINWHERE條件。

請注意,在product_idcategory_id上有單獨的索引是不夠的。但是,如果您有(category_id, product_id)上的複合索引,則可以刪除(category_id)上的索引,除非它是唯一索引(如主鍵)。

+0

嗨,我添加了複合索引,但我在EXPLAIN – Kevin

+0

中獲得完全相同的結果,嘗試對錶1和表2進行「優化」 - 它可能會更改查詢規劃器對最佳查詢計劃的選擇 – mvp