2012-03-15 52 views
2

我有一個查詢,使一些連接。我有什麼索引到這個數據庫?

SELECT feedback.note as notes, 
to_char(feedback.data_compilazione,'DD/MM/YYYY') as date, 
CAST(feedback.punteggio AS INT) as score, 
upper(substring(cliente.nome from '^.') || '.' || 
substring(cliente.cognome from '^.') || '.') as customer, 
testo.testo as nation FROM feedback 
JOIN prenotazione ON prenotazione.id = feedback.id_prenotazione 
JOIN cliente ON cliente.id = prenotazione.id_cliente 
JOIN struttura ON struttura.id = prenotazione.id_struttura 
JOIN lingua ON cliente.id_lingua = lingua.id 
JOIN nazione ON cliente.codice_nazione = nazione.codice_iso 
JOIN testo ON testo.nome_tabella = 'nazione' AND testo.id_record = nazione.id AND 
testo.id_lingua = lingua.id AND testo.id_tipo_testo = 1 WHERE struttura.id = 43 AND 
lingua.sigla = E'en' AND feedback.punteggio >= 3 AND feedback.note <> '' 
ORDER BY feedback.data_compilazione DESC LIMIT 5 

我的問題是我沒有任何顯式索引到我的表上。

這意味着這個查詢需要很長很長很長時間才能執行。

AFAIK postresql創建一個「隱含的」指數每次申報一個主鍵,所以我沒有加入它「明確」。

這是查詢

"Limit (cost=212.72..212.73 rows=1 width=208)" 
" -> Sort (cost=212.72..212.73 rows=1 width=208)" 
"  Sort Key: feedback.data_compilazione" 
"  -> Nested Loop (cost=1.11..212.71 rows=1 width=208)" 
"    -> Nested Loop (cost=1.11..206.86 rows=1 width=212)" 
"     Join Filter: (("outer".codice_nazione)::text = ("inner".codice_iso)::text)" 
"     -> Nested Loop (cost=1.11..201.63 rows=1 width=223)" 
"       -> Nested Loop (cost=1.11..195.60 rows=1 width=187)" 
"        Join Filter: ("outer".id = "inner".id_cliente)" 
"        -> Nested Loop (cost=1.11..45.18 rows=1 width=183)" 
"          Join Filter: ("outer".id_lingua = "inner".id_lingua)" 
"          -> Index Scan using testo_pkey on testo (cost=0.00..6.27 rows=1 width=40)" 
"           Index Cond: (((nome_tabella)::text = 'nazione'::text) AND (id_tipo_testo = 1))" 
"          -> Hash Join (cost=1.11..38.86 rows=4 width=155)" 
"           Hash Cond: ("outer".id_lingua = "inner".id)" 
"           -> Seq Scan on cliente (cost=0.00..33.47 rows=847 width=151)" 
"           -> Hash (cost=1.11..1.11 rows=1 width=4)" 
"             -> Seq Scan on lingua (cost=0.00..1.11 rows=1 width=4)" 
"              Filter: ((sigla)::text = 'en'::text)" 
"        -> Seq Scan on prenotazione (cost=0.00..150.05 rows=30 width=12)" 
"          Filter: (43 = id_struttura)" 
"       -> Index Scan using feedback_id_prenotazione_key on feedback (cost=0.00..6.01 rows=1 width=44)" 
"        Index Cond: ("outer".id = feedback.id_prenotazione)" 
"        Filter: ((punteggio >= 3::double precision) AND (note <> ''::text))" 
"     -> Index Scan using nazione_pkey on nazione (cost=0.00..5.21 rows=1 width=11)" 
"       Index Cond: ("outer".id_record = nazione.id)" 
"    -> Index Scan using struttura_pkey on struttura (cost=0.00..5.82 rows=1 width=4)" 
"     Index Cond: (id = 43)" 

所以我停下來思考關於DB索引的EXPLAIN。 創建索引的最佳做法是什麼? 解決方案是:爲每個連接的字段創建一個索引?

而進入我的數據庫,你有什麼建議給指數?

我已經做了一些嘗試(實際上指數每一個被聯接的字段)和查詢運行速度更快,但並不快(約6秒以檢索零行)。 我想我的解決方案不是最好的。

有人可以指着我的眼光看正確的方向嗎?

編輯

如果我添加一個索引(上prenotazione.id_cliente)在極少數秒(約1.5),所有的作品。那麼,爲什麼在FOREIGN鍵上添加所有索引會使我的查詢運行速度變慢?

+0

它看起來像表已經至少部分索引。其他一些考慮因素是字符串的contatenation,並且有幾個序列掃描(而不是索引掃描),最後確保您的索引策略是正確的(查找Postgresql索引類型)。 – swasheck 2012-03-15 17:00:44

+0

您能向我們展示EXPLAIN ANALYSE的結果嗎?這也向我們展示了每一步的時間,這是你問題中最重要的因素。 – 2012-03-16 07:57:24

+0

@FrankHeikens:現在我已經添加了一個索引,這是行得通的,所以我要刪除索引並執行E.A. ? :( – DonCallisto 2012-03-16 08:01:31

回答

3

根據經驗的第一條規則,看也不看查詢計劃,我一定會穿上具有高(> 100個不同的值)的選擇性外鍵索引。

有些數據庫沒有問他們,Postgres沒有。 我們正在討論FOREIGN鍵上的索引,而不是主鍵索引(顯然總是提供這些索引)。

例如,prenotazione.id_struttura,並且feedback.id_prenotazione都是可能的候選者。

另一方面,7個不同值的weekday列不會從索引中受益,除非有成千上萬的星期一和非常少的星期日,在這種情況下,索引對某些值是有選擇性的。

+0

如果我很少秒(約1.5),添加一個索引(上prenotazione.id_cliente)所有的作品。那麼,爲什麼加上外鍵的索引使我的查詢運行慢? – DonCallisto 2012-03-15 17:12:38

+0

BTW你的答案是好的,如果沒有人會回答比你更好,我會接受這個,但我很好奇我之前給你的評論,你有什麼想法嗎?只是爲了理解整個過程,並在將來再次 – DonCallisto 2012-03-16 08:48:21

+1

一個可能的原因:如果這些值很少且均勻分佈,那麼每個數據頁面可能會同時包含所有的值,因此通過索引訪問需要更多的間接性,更多的尋找並最終檢索相同的數據。表掃描可以更快,這取決於表格大小和其他一些東西。順序訪問期間非SSD硬盤的速度要快上百倍。 Postgres是否決定使用索引,取決於統計數據等等。我建議看一下O'Reilly編寫的「重構SQL應用程序」,不是太難,但有效並且很有啓發性。 – 2012-03-16 10:23:20

相關問題