首页 > 解决方案 > 为什么两个查询的联合比单个联合查询更快?

问题描述

我正在使用 Autovacuuming 调试 2x Google Cloud SQL Postgres 9.6 实例中的查询时间。暂存(无流量)7.5gb + 2vCPU。和生产:37.5gb,10vCPU。结果相同且令人困惑。

索引:

始终保持 100-120 毫秒:

SELECT * FROM "Trade" WHERE "user1" = 1
UNION
SELECT * FROM "Trade" WHERE "user2" = 1
LIMIT 24;
Limit  (cost=221.92..222.16 rows=24 width=1187) (actual time=0.115..0.124 rows=24 loops=1)
  ->  HashAggregate  (cost=221.92..222.46 rows=54 width=1187) (actual time=0.115..0.121 rows=24 loops=1)
        Group Key: id, status, user1, user2
        ->  Append  (cost=4.60..218.55 rows=54 width=1187) (actual time=0.024..0.076 rows=26 loops=1)
              ->  Bitmap Heap Scan on "Trade"  (cost=4.60..89.99 rows=22 width=155) (actual time=0.024..0.061 rows=23 loops=1)
                    Recheck Cond: (user1 = 1)
                    Heap Blocks: exact=20
                    ->  Bitmap Index Scan on trade_depositor_user_id  (cost=0.00..4.59 rows=22 width=0) (actual time=0.016..0.016 rows=23 loops=1)
                          Index Cond: (user1 = 1)
              ->  Bitmap Heap Scan on "Trade" "Trade_1"  (cost=4.67..128.02 rows=32 width=155) (actual time=0.011..0.014 rows=3 loops=1)
                    Recheck Cond: (user2 = 1)
                    Heap Blocks: exact=3
                    ->  Bitmap Index Scan on trade_withdrawer_user_id  (cost=0.00..4.67 rows=32 width=0) (actual time=0.009..0.009 rows=3 loops=1)
                          Index Cond: (user2 = 1)
Planning time: 0.224 ms
Execution time: 0.189 ms

始终为 280-350 毫秒:

SELECT * FROM "Trade" WHERE "user1" = 1
Bitmap Heap Scan on "Trade"  (cost=4.60..89.99 rows=22 width=155) (actual time=0.023..0.054 rows=23 loops=1)
  Recheck Cond: (user1 = 1)
  Heap Blocks: exact=20
  ->  Bitmap Index Scan on trade_user1  (cost=0.00..4.59 rows=22 width=0) (actual time=0.015..0.015 rows=23 loops=1)
        Index Cond: (user2 = 1)
Planning time: 0.077 ms
Execution time: 0.078 ms

两个查询都返回相同的结果集大小。我尝试了更简单查询的不同变体,例如按 ID ASC/DESC 排序。

标签: postgresqlgoogle-cloud-sqlpostgresql-9.6

解决方案


您应该使用UNION ALL, 简单地连接结果,而不是UNION,通常通过排序来消除结果的重复数据,以进行公平比较。

由于重复数据删除操作的存在,优化器可能会感到困惑并且正在使用不同的启发式算法,并且小行数会导致没有意义的边缘情况。


推荐阅读