2011-10-06 47 views
2

最近我在Windows7機器上安裝了PostgreSQL 9.0 w/Postgis。然後,我將幾個表加載到一個模式中。 現在,我想做一個非常簡單的查詢,在這個時候,我可以看到它需要更多的10分鐘。 我已經通過很多地方搜索,也在stackoverflow.com,直到現在我可以理解我的錯誤是什麼。PostgreSql使用IN狀態的性能非常低

我的問題:

Tbl_Proprietarios - 230000個紀錄

Tbl_Predio - 160000個紀錄

SELECT id_predios 
FROM "Tbl_Predio" 
where id_predios not in 
    (
    SELECT id_predios 
    FROM "Tbl_Proprietarios" 
    ) 
; 

感謝

+1

你有兩個表中的'id_predios'列的索引嗎? – Xint0

+0

是的,我已經(忘記告訴) – galacha

+0

id_predios的數據類型在兩個表中都是相同的(大概是整數)? – wildplasser

回答

0

應該在幾秒鐘內一個體面的機器上運行。 表定義?索引?查詢計劃?配置?記憶?

SELECT id_predios 
FROM Tbl_Predio t1 
WHERE NOT EXISTS ( 
    SELECT * 
    FROM Tbl_Proprietarios t2 
    WHERE t2.id_predios = t1.id_predios 
) 
; 

編輯:

Hash Anti Join (cost=29813.47..61463.98 rows=79 width=4) (actual time=3470.658..7142.042 rows=1045 loops=1) 
    Hash Cond: (t1.id_predios = t2.id_predios) 
    -> Seq Scan on tbl_predio t1 (cost=0.00..13912.33 rows=999033 width=4) (actual time=0.038..1458.946 rows=999033 loops=1) 
    -> Hash (cost=13911.54..13911.54 rows=998954 width=4) (actual time=3238.919..3238.919 rows=998954 loops=1) 
     -> Seq Scan on tbl_proprietarios t2 (cost=0.00..13911.54 rows=998954 width=4) (actual time=0.057..1479.807 rows=998954 loops=1) 
Total runtime: 7143.919 ms 
(6 rows) 

EDIT2: 測試腳本:

DROP SCHEMA tmp CASCADE; 
CREATE SCHEMA tmp; 

DROP TABLE tmp.Tbl_Predio CASCADE; 
DROP TABLE tmp.Tbl_Proprietarios CASCADE; 

CREATE TABLE tmp.Tbl_Predio (id_predios INTEGER NOT NULL); 
CREATE TABLE tmp.Tbl_Proprietarios (id_predios INTEGER NOT NULL); 

INSERT INTO tmp.Tbl_Predio (id_predios) SELECT serie.val 
    FROM generate_series(1,1000000) AS serie(val) 
    ; 

INSERT INTO tmp.Tbl_Proprietarios (id_predios) SELECT serie.val 
    FROM generate_series(1,1000000) AS serie(val) 
    ; 

DELETE FROM tmp.Tbl_Predio WHERE random() <= 0.001 ; 
DELETE FROM tmp.Tbl_Proprietarios WHERE random() <= 0.001 ; 

ALTER TABLE tmp.Tbl_Predio ADD PRIMARY KEY (id_predios) ; 
ALTER TABLE tmp.Tbl_Proprietarios ADD PRIMARY KEY (id_predios) ; 

EXPLAIN ANALYZE 
SELECT id_predios 
FROM tmp.Tbl_Predio t1 
WHERE NOT EXISTS (
    SELECT * 
    FROM tmp.Tbl_Proprietarios t2 
    WHERE t2.id_predios = t1.id_predios 
) 
; 
+0

您的查詢建議也很慢:( – galacha

+0

我應該檢查哪種配置標誌? – galacha

+0

您的表定義和查詢計劃也很慢:-) – wildplasser

2

嘗試左外連接:

SELECT Tbl_Predio.id_predios 
FROM Tbl_Predio 
LEFT OUTER JOIN Tbl_Proprietarios ON Tbl_Predio.id_predios = Tbl_Proprietarios.id_predios 
WHERE Tbl_Proprietarios.id_predios IS NULL; 
2個* 999K記錄的查詢計劃

另外,請確保Tbl_Proprietarios.id_predios上有索引。

0

根據我在SQL Server的經驗in運營商通常是非常緩慢的。

通常是更好exists

SELECT id_predios 
    FROM "Tbl_Predio" 
WHERE not exists (
      SELECT 1 
      FROM "Tbl_Proprietarios" 
      WHERE "Tbl_Proprietarios".id_predios = "Tbl_Predio".id_predios 
     ) 

(注意在MySQL通常情況相反,但在邏輯上取決於你所運行的查詢)

或者你可以使用左連接:

SELECT id_predios 
    FROM "Tbl_Predio" 
    left join "Tbl_Proprietarios" on "Tbl_Proprietarios".id_predios = "Tbl_Predio".id_predios 
WHERE "Tbl_Proprietarios".id_predios is null 

要知道發生了什麼,請使用EXPLAIN

+0

我不知道如何,但你的querys快速和....我已經嘗試使用存在和左JOIN的..... 在這2天后...更好地吃點心! 謝謝 – galacha