PostgreSQL连接获取表中的所有行,速度太慢

时间:2014-11-11 23:50:45

标签: postgresql inner-join query-performance postgresql-performance

我有两个表“佣金”和“mt4_trades”。在“mt4_trades”中,“ticket”列是私钥,在“佣金”中有“order_id”,并且它与mt4_trades.ticket有一对多(一个“票”到很多“order_id”)。我有这样的声明:

SELECT commissions.ibs_account AS ibs_account                      
       FROM "public"."mt4_trades" 
    INNER JOIN commissions ON commissions.order_id = mt4_trades.ticket 
        WHERE "mt4_trades"."close_time" >= '2014.11.01' 
          AND "mt4_trades"."close_time" < '2014.12.01'

佣金表约为4百万行。此语句返回480000行。但它太慢了:执行时间 9秒。我做了EXPLAIN ANALYZE:

Hash Join  (cost=43397.07..216259.97 rows=144233 width=7) (actual time=3993.839..9459.896 rows=488131 loops=1)
  Hash Cond: (commissions.order_id = mt4_trades.ticket)
  ->  Seq Scan on commissions  (cost=0.00..116452.08 rows=3997708 width=15) (actual time=0.005..4185.254 rows=3997157 loops=1)
  ->  Hash  (cost=42485.10..42485.10 rows=72958 width=4) (actual time=288.767..288.767 rows=97260 loops=1)
        Buckets: 8192  Batches: 1  Memory Usage: 3420kB
        ->  Index Scan using "INDEX_CLOSETIME" on mt4_trades  (cost=0.43..42485.10 rows=72958 width=4) (actual time=0.020..174.810 rows=97260 loops=1)
              Index Cond: ((close_time >= '2014-11-01 00:00:00'::timestamp without time zone) AND (close_time < '2014-12-01 00:00:00'::timestamp without time zone))
Total runtime: 9881.979 ms

这一行:

->  Seq Scan on commissions  (cost=0.00..116452.08 rows=3997708 width=15) (actual time=0.005..4185.254 rows=3997157 loops=1)

意味着扫描整个“佣金”表,而不是首先比较“order_id”和“ticket”。 你能帮助我如何改进这个查询吗?感谢

1 个答案:

答案 0 :(得分:1)

返回50万行的9秒并不可怕,4M上的顺序扫描比4M上的100K索引查找要快得多。假设你有一个order_id的索引,你可以在运行查询之前运行set enable_seqscan TO false;来测试它(这只会影响当前的连接)。

每次运行此查询时,您真的需要所有500K行吗?或者你要过滤结果?如果您几乎总是以某种其他方式过滤结果,那么您可能希望优化该查询而不是返回所有500K行的查询。