PostgreSQL join 获取表中的所有行,太慢了

Posted

技术标签:

【中文标题】PostgreSQL join 获取表中的所有行,太慢了【英文标题】:PostgreSQL join fetch all rows in table, too slow 【发布时间】:2014-11-11 23:50:45 【问题描述】:

我有两个表“commissions”和“mt4_trades”。在“mt4_trades”中,“ticket”列是私钥,在“commissions”中有“order_id”,它与 mt4_trades.ticket 是一对多的(一个“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'

commissions 表包含大约 400 万行。此语句返回 480000 行。但它太慢了:执行时间 9 秒。我做了解释分析:

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)

扫描整个“commissions”表而不是首先比较“order_id”和“ticket”的意思。 你能帮我如何改进这个查询吗?谢谢

【问题讨论】:

您是否已将commissions.order_id 编入索引? 将这些表的 CREATE TABLE 语句粘贴到您的问题中。通过运行analyze commissions; analyze mt4_trades; 更新统计信息。然后再次explain analyze your-query @tsnorri:除非 OP 还可以向 ibs_account 添加 WHERE 条件,否则索引可能对这个哈希连接没有帮助。 【参考方案1】:

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

您真的每次运行此查询时都需要全部 500K 行吗?还是要过滤结果?如果您几乎总是要以其他方式过滤结果,您可能希望针对该查询而不是返回所有 500K 行的查询进行优化。

【讨论】:

感谢您的回答!我有

以上是关于PostgreSQL join 获取表中的所有行,太慢了的主要内容,如果未能解决你的问题,请参考以下文章

优化 PostgreSQL 中的 JOIN -> GROUP BY 查询:所有索引都已经存在

UNION JOIN 连接表

一张图看懂Mysql的join连接

SQL连接(join)

如何使用Yii2中的left join从两个表中获取所有列数据

如何从大表中读取所有行?