2010-08-31 48 views
0

我在「操作員」字段有一個300K行和b-tree索引的表。 雖然我運行這個查詢它不使用索引。 「運算符」與dict.vw_dict_operator.id具有相同的數據類型。爲什麼這個查詢沒有使用索引?

EXPLAIN SELECT 
    id, 
    name 
FROM 
    dict.vw_dict_operator self 
WHERE 

      EXISTS (
       SELECT 42 FROM ti.ti_flight_availability flight_avail 
       WHERE flight_avail.operator = self.id 
      ) 
ORDER BY 
    self.name 

"Sort (cost=3349.66..3351.02 rows=545 width=18)" 
" Sort Key: dict_operator.name" 
" -> Seq Scan on dict_operator (cost=0.00..3324.89 rows=545 width=18)" 
"  Filter: ((NOT trash) AND (subplan))" 
"  SubPlan" 
"   -> Seq Scan on ti_flight_availability flight_avail (cost=0.00..8513.66 rows=3750 width=0)" 
"    Filter: (operator = $0)" 

UPD:thanks @gbn。當連接表時也不會使用索引

EXPLAIN SELECT self.id, self.name 
FROM dict.vw_dict_operator self JOIN ti.ti_flight_availability flight_avail 
ON flight_avail.operator = self.id 

"Nested Loop (cost=0.00..92988.47 rows=228639 width=18)" 
" -> Seq Scan on ti_flight_availability flight_avail (cost=0.00..7754.33 rows=303733 width=4)" 
" -> Index Scan using pk_dict_operator on dict_operator (cost=0.00..0.27 rows=1 width=18)" 
"  Index Cond: (dict_operator.id = flight_avail.operator)" 
"  Filter: (NOT dict_operator.trash)" 
+0

我不知道如何使用索引,但依賴子查詢通常是不好的mojo。 – Powerlord 2010-08-31 19:24:20

+0

@ R. Bemrose你可以在沒有子查詢的情況下編寫這個任務的實現嗎? – noxvile 2010-08-31 19:39:48

回答

2

爲什麼不使用JOIN?你分析過嗎?統計數字呢?查看此表的pg_stats以獲取更多信息。在pg_class中reltuples和relpages對於表和它的索引也很有趣。


編輯: 聯接期望228639行。順序掃描需要303733行,只有一小部分額外。當這些100k記錄遍佈整個地方時,數據庫無論如何都必須掃描相關鏈接。順序掃描將比索引掃描更快,順序掃描(快速)sequentail讀取,索引掃描將是兩個(!)慢速隨機讀取:來自索引的信息來自表中的數據。

如果您認爲該計劃有誤,請分析該表並向我們顯示pg_stats和pg_class有關表和索引的信息。

ANALYZE; 

SELECT relpage, reltuples WHERE relname = 'table_or_index_name'; 

SELECT * FROM pg_stats WHERE tablename = 'name of your table'; 
+0

對不起,JOIN也不使用索引。執行ANALYZE需要很長時間。 reltuples:303733 relpages:4717 不幸的是,我不知道我可以從pg_class獲取什麼有用的信息,pg_stats – noxvile 2010-08-31 19:29:53

+0

請參閱我的編輯,並且您必須ANALYZE。你可以在這些桌子上做,但你必須這樣做。你有什麼版本的PostgreSQL? – 2010-08-31 19:35:28

+0

版本8.3 reltuples:303733 relpages:4717 http://img203.imageshack.us/img203/1516/screenshotrz.png – noxvile 2010-08-31 19:56:56

0

如果您進行了連接,它會使用索引嗎?

0

你對dict.vw_dict_operator有什麼索引?

EXISTS是JOIN的一種形式(我知道這是簡單的),因爲沒有方便的JOIN可以忽略索引。所以它會掃描。

編輯:

的連接計劃沒有使用上ti_flight_availability指數要麼...但你說明你有它的指數?

+0

CREATE TABLE dict.dict_operator ( ID整數NOT NULL, 約束pk_dict_operator PRIMARY KEY(ID) ) – noxvile 2010-08-31 19:18:14

+0

@noxvile:和ti_flight_availability? – gbn 2010-08-31 19:19:53

+0

CREATE INDEX ix_ti_flight_availability_operator ON ti.ti_flight_availability 使用btree (運算符); – noxvile 2010-08-31 19:21:27

相關問題