【发布时间】:2014-04-23 23:31:38
【问题描述】:
考虑两个 PostgreSQL 表:
表 #1
id INT
secret_id INT
title VARCHAR
表#2
id INT
secret_id INT
我需要从表#1 中选择所有记录,但排除表#2 跨越secret_id 值。
以下查询非常慢,表 #1 中有 1 000 000 条记录,Table #2 中有 500 000 条记录:
select * from table_1 where secret_id not in (select secret_id from table_2);
实现这一目标的最佳方法是什么?
【问题讨论】:
-
问题是,究竟是什么,我猜如何让它更快?你看过查询计划(
EXPLAIN/EXPLAIN ANALYZE)吗? “非常慢”有多慢?你有索引吗?这些 ID 的分布是什么 - 如果每一行都有一个唯一的secret_id,那么您的示例将返回 500000 行,这无论如何都会很慢? -
您需要提高
work_mem设置的可能性很大,但您可能会发现设置SELECT * FROM table_1 EXCEPT SELECT t1.* FROM table_1 t1 JOIN table_2 t2 ON t1.secret_id = t2.secret_id会更快 -
你也可以试试不直观的
SELECT t1.* FROM table_1 t1 LEFT JOIN table_2 t2 ON t1.secret_id = t2.secret_id WHERE t2.secret_id IS NULL。 -
改用
NOT EXISTS,或者像 Daniel Lyons 建议的那样使用左反连接。并显示EXPLAIN ANALYZE输出。
标签: sql postgresql query-optimization