2013-02-24 90 views
3

我有一個非常簡單的查詢,基本上是這樣的速度很慢查詢(varchar 255)當匹配的文本字段不爲空字符串

查詢需要大約39,000ms才能運行。我在猜測,因爲它不得不通過每個記錄來查看非空字符串的事情。我已經索引了my_field列,但它沒有改變任何東西。

萬一它的任何使用,這裏是查詢計劃:

"Seq Scan on my_table (cost=0.00..3468.91 rows=39744 width=459)" 
" Filter: ((my_field)::text <> ''::text)" 

什麼,這裏是我最好的選擇?

解釋分析:

"Seq Scan on my_table (cost=0.00..3468.91 rows=39730 width=459) (actual time=0.021..13.763 rows=39714 loops=1)" 
" Filter: ((my_field)::text <> ''::text)" 
"Total runtime: 14.856 ms" 

我添加了這些指標

CREATE INDEX aa_idx ON my_table(my_field); 
CREATE INDEX aa_idx ON my_table(my_field) WHERE my_field <> ''; 

它的Postgres 9.1

編輯:2013年2月26日00:04GMT]

在「m」上創建分區會有什麼好處嗎? y_field「作爲檢查約束?

像CHECK(my_field =「」)和分區2 CHECK(my_field!=「」)

我猜那麼我就必須是一個有很多在這行的表?但是,這意味着即使分區將包含大約80%的數據,select!=''查詢的執行速度也會快得多嗎?

我也看了全文搜索,但這似乎是一個OTT。我也看着使列爲0或1(布爾)的int,但這對性能沒有影響(我猜因爲= 1仍然帶回很多行?)

+0

1)具有(非)空my_field的記錄的概率是多少:有多少記錄滿足條件? 2)你是否有統計數據(你是否在添加索引後運行'vacuum analyze')? – wildplasser 2013-02-24 23:34:04

+0

1)通常情況下,我會說大約75%的字段與查詢匹配。2)是的,我之後進行了真空全分析。我也嘗試添加my_field <>''的部分索引,但沒有任何區別。 – TheStoneFox 2013-02-24 23:39:36

+0

最好顯示'解釋分析'不只是簡單的'解釋'。另外:PostgreSQL版本?你的數據庫在哪個區域?並請顯示您添加的索引的定義。 – 2013-02-24 23:41:47

回答

2

索引不會幫助你。我認爲你需要找到一個更好的方法來整合你的刪除。

您說它運行需要39秒,但您提供的實際查詢計劃需要15毫秒才能運行,這大約是2000年的一個因子。除非我們正在討論帶有大量TOASTed值的非常寬泛的表格,否則我很難想象緩存會有多大幫助。這告訴我實際的問題不在你的選擇中,而是在你的管道中的其他地方。這可能包括往返費用,但是您正在執行刪除操作。

我的建議是看看聲明合併。這將意味着避免往返並儘可能多地將邏輯推入單個查詢中。既然你還沒有發佈完整的上下文,我建議你可能希望查看可寫CTE的批處理插入,更新和刪除一起沒有往返旅程。