2012-03-02 68 views
2

我有兩個查詢,插入和更新。我通過postgres控制檯與一個大型數據集做了一個基準測試,發現postgres沒有拿起索引。爲了解決這個問題 - 我禁用了這兩個查詢的seqscan並獲得了巨大的性能提升; Postgres能夠拿起索引在桌子上掃描。通過jdbc |設置enable_seqscan = off Postgres

問題: 我做同樣的事情通過JDBC

statement.executeUpdate("set enable_seqscan = off"); 
statement.executeUpdate("My_Insert_Query"); 
statement.executeUpdate("My_Update_Query"); 
statement.executeUpdate("set enable_seqscan = on"); 

但好像是Postgres的不轉彎seq_scan關閉和查詢採取了太多的時間來執行。

主表

Master_Id auto-generated 
child_unique  integer 


Child Table 
child_unique integer 
Master_id integer 

Insert into Master (child_unique) from Child as i WHERE NOT EXISTS (SELECT * from Master where Master.child_unique = i.child_unique); 

Update Child set Master_id = Master.Master_id from Master where Master.child_unique = Child.child_unique; 

對於每個孩子獨特的行主 - 我插入到我的主表,並得到自動生成的Master_ID並插入它放回子表中不存在。

這兩個表都有child_unique的索引。

索引在主表上被拾取,因爲它不在子表的情況下。 我是如何知道的?使用Postgres的pg_stat_all_indexes表。

+0

有些參數只能由超級用戶更改(我不知道哪些參數),所以如果您的應用使用不同的用戶,那麼您在控制檯上可能會出現問題。另外建議不要關閉順序掃描,而是調整服務器的規劃器成本常量:http://www.postgresql.org/docs/9.1/interactive/runtime-config-query.html#RUNTIME-CONFIG-QUERY -CONSTANTS。如果您的數據庫幾乎完全符合內存要求,可以快速啓動,使random_page_cost等於seq_page_cost。另外請確保您的數據已被正確分析。 – Eelke 2012-03-02 06:57:54

+2

你爲什麼不試着解決真正的問題?爲什麼PostgreSQL認爲使用索引不是一個好主意?您能向我們展示EXPLAIN和/或EXPLAIN ANALYSE的結果嗎? – 2012-03-02 07:03:49

+0

您是否確認seqscan確實已關閉?關掉後是否檢查執行計劃? – 2012-03-02 17:41:21

回答

1

首先,我贊同上面的弗蘭克 - 解決真正的問題。

但是,如果您確實想禁用seq-scans,則您未能提供任何信息來幫助您這麼做。

這些語句是否都在同一個連接上執行? (在PostgreSQL的配置文件中打開/關閉日誌以查找)

是否有任何其他jdbc生成的位正在發送到服務器? (再次登錄)

「show enable_seqscan」在第一條語句後返回什麼?

+1

注意:Child是在應用程序內動態創建的,並且在同一個事務中創建了上述SQL查詢。我發現如果我在不同的事務中創建Child表並提交它,我不再有這個問題。 現在的問題是,爲什麼它不在相同的事務中提取索引? – KarthikRajagopal 2012-03-05 02:43:43

+0

看起來像ANALYZE的一個問題:當創建新記錄時,auto_vacuum(同時負責自動分析)開始。但只有在提交後,使用它自己的數據庫連接。使用ANALYZE Child;在插入之後,使用您當前的連接,並查看查詢計劃中是否有任何區別。 – 2012-03-05 07:13:07