database - Postgres ANTI-JOIN 需要表扫描?

标签 database postgresql indexing anti-join

我需要在同一张表上进行反连接(不存在从表中选择内容.../左连接表 WHERE table.id IS NULL)。实际上我有一个索引来解决不存在的问题,但查询规划器选择使用位图堆扫描。

该表有 1 亿行,因此进行堆扫描很困惑...

如果 Postgres 可以与索引进行比较,那将是非常快的。 Postgres 是否必须访问此 ANTI-JOIN 的表?

我知道必须在某个时候访问该表才能为 MVCC 服务,但为什么这么早? NOT EXISTS 不能只由表修复,否则它可能会遗漏一些东西吗?

最佳答案

您需要提供版本详细信息,正如 jmz 所说,EXPLAIN ANALYZE 输出以获得任何有用的建议。

Franz - 不要想这是否可能,测试并知道。

这是 v9.0:

CREATE TABLE tl (i int, t text);
CREATE TABLE tr (i int, t text);
INSERT INTO tl SELECT s, 'text ' || s FROM generate_series(1,999999) s;
INSERT INTO tr SELECT s, 'text ' || s FROM generate_series(1,999999) s WHERE s % 3 = 0;
ALTER TABLE tl add primary key (i);
CREATE INDEX tr_i_idx ON tr (i);
ANALYSE;
EXPLAIN ANALYSE SELECT i,t FROM tl LEFT JOIN tr USING (i) WHERE tr.i IS NULL;
                                                         QUERY PLAN                                                      
-----------------------------------------------------------------------------------------------------------------------------
 Merge Anti Join  (cost=0.95..45611.86 rows=666666 width=15) (actual time=0.040..4011.970 rows=666666 loops=1)
   Merge Cond: (tl.i = tr.i)
   ->  Index Scan using tl_pkey on tl  (cost=0.00..29201.32 rows=999999 width=15) (actual time=0.017..1356.996 rows=999999 lo
   ->  Index Scan using tr_i_idx on tr  (cost=0.00..9745.27 rows=333333 width=4) (actual time=0.015..439.087 rows=333333 loop
 Total runtime: 4602.224 ms

您看到的内容取决于您的版本,以及规划师看到的统计数据。

关于database - Postgres ANTI-JOIN 需要表扫描?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5274851/

相关文章:

MySQL "set unique_checks"、 "set foreign_key_checks"与 "alter table disable keys"

android - 如何使用推送通知同步 SQLite 和 MySQL 数据库?

regex - 如何将正则表达式与任何数组运算符一起使用

ruby-on-rails - 我如何使用事件记录从 foren 表中进行选择

python - sqlalchemy手动创建数据库表

python - 索引超出迭代范围

php - 需要帮助格式化返回的 SQL 数据

database - 查询在触发后没有结果数据的目的地

sql - 在 Oracle 中插入空字符串

mySQL 非聚集索引 + 非索引字段是否仍然比 2 x 非索引字段快?