2017-04-21 102 views
0

我有一個表SQL查詢的運行速度比預期慢

foo(a1, a2, a3, a4, a5) 

a1是主鍵。 a5上有一個非聚類索引。

我有一個簡單的查詢:

SELECT * 
FROM foo 
WHERE a5/100 = 20; 

此查詢運行顯著慢。更新查詢計劃中使用的統計數據並沒有多大幫助。

爲什麼會發生這種情況? 我能做什麼錯? 我是新來的查詢優化。

+0

慢又算得了什麼?請提供執行計劃。 –

+8

'WHERE a5/100 = 20;' - >嘗試'WHERE a5 = 2000;'而是確保在'a5'列上創建了一個索引。 – krokodilko

+0

請** [編輯] **你的問題,並添加使用**解釋(分析,詳細)'**生成的執行計劃。 [**格式化文本**](http://stackoverflow.com/help/formatting)請,[無屏幕截圖](http://meta.stackoverflow.com/questions/285551/why-may-i-not上傳圖片的代碼時這樣問/ 285557#285557) –

回答

0

您在WHERE謂詞中的列上使用了一個表達式,因此它不是sargable(不能使用索引)。

這是撇開可能的基數問題,即數據分佈 - 如果您的WHERE條件返回超過40%左右的行索引變得無用。

編輯

在你搜索的值,如果這個值是一個表達式的結果指標是不能忽視的used.Also運營商像一個指標:NOT,NOT IN,<>也沒有,可優化搜索,因爲對於索引搜索,您需要明確的值,以便優化程序可以定義某種固定範圍。隨着您的計算,數值會不斷變化,因此您需要掃描整個表格。

+0

感謝您的迴應。請您詳細說明一下。這似乎相當濃縮。 – foobar

+1

「<>」或「NOT IN」不能使用索引並不完全正確。使用'where ... <> ...'定義的部分索引可能適用於這種情況 –

+0

我有一個額外的後續問題:如果在具有一些缺失/ null的列上創建了非集羣索引,會發生什麼情況值? – foobar

0

您可以在表達式上創建索引而不是基礎數據。如果你知道你總是將a5除以100,你可以使用下面的索引:

CREATE INDEX ON foo ((a5/100)); 

需要額外的括號。

這樣,任何具有WHERE a5/100 = <something>的查詢都將能夠利用索引。

它不會幫助WHERE a5/99 = <something>等雖然

文檔在https://www.postgresql.org/docs/current/static/indexes-expressional.html