2016-07-29 200 views
1

伊夫很奇怪的問題,當我執行類似下面的查詢的奇怪表現:,Postgres的查詢

with ap as (
    SELECT id from adress limit 1000) 
) 

SELECT distinct house.id, house.date 
FROM house 
WHERE house.adressid in (select id from ap) 

LIMIT 9999 

我GE 100毫秒

但是,當我更改限制到10,然後即時得到一個內resulkts後導致20秒

with ap as (
    SELECT id from adress limit 1000) 
) 

SELECT distinct house.id, house.date 
FROM house 
WHERE house.adressid in (select id from ap) 

LIMIT 10 

當然有上adressid

索引3210

在房子裏有9百萬行。

有沒有人有一個想法hoiw我可以嘗試提高性能。香港專業教育學院減少了問題這個非常簡單的一個,但在現實中的結構要複雜得多這就是爲什麼我沒有爲你提供表中創建和查詢計劃...

+3

我會用EXPLAIN分析並找到如何PostgreSQL的實際處理兩個查詢開始。 – Gary

+0

您可能過於簡化了查詢。 Postgres(除非它有一些非常不尋常的優化)應該爲這兩個查詢做同樣的工作 - 它必須在應用外部'limit'之前生成'select distinct'的整個列表。可能還有其他事情正在發生。 –

+0

其實這是我改變的唯一的東西 – Snorlax

回答

0

這實際上並不奇怪:

在第一case ap最多有1000行,結果集應該高達9999,所以優化器首先放adress。有索引house查詢性能比較高。

在第二種情況下ap仍然有多達1000行,但結果集應該只有最多10個,所以優化投入house第一......與上adress 10次表掃描結束了長達1000行每。由於任何地方都沒有Order By子句,它可能甚至不能使用索引。

limit 1000上的地址看起來很可疑,可能會導致不一致的結果:沒有Order By難保從adress記錄每次運行時會予以考慮。

我會用INNER JOIN來解決問題:

SELECT DISTINCT house.id, house.date 
FROM house 
INNER JOIN adress ON adress.id = house.adressid 
ORDER BY house.date --< To add some consistency 
LIMIT 10