2016-07-29 202 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