Sql 查询计划:连接的顺序重要吗

Sql 查询计划:连接的顺序重要吗,sql,postgresql,query-planner,Sql,Postgresql,Query Planner,我想检查连接顺序在SQL查询中对于运行时和效率是否很重要 我使用的是PostgreSQL,为了便于检查,我使用了MYSQL中的示例world db,并编写了以下两条语句: 问题1: 从countrylanguage解释分析选择* 在city.countrycode=countrylanguage.countrycode上加入城市 在city.countrycode=c.code上加入国家c 问题2: 解释分析从城市中选择* 在c.code=city.countrycode上加入国家c 在c.co

我想检查连接顺序在SQL查询中对于运行时和效率是否很重要

我使用的是PostgreSQL,为了便于检查,我使用了MYSQL中的示例world db,并编写了以下两条语句:

问题1:

从countrylanguage解释分析选择* 在city.countrycode=countrylanguage.countrycode上加入城市 在city.countrycode=c.code上加入国家c 问题2:

解释分析从城市中选择* 在c.code=city.countrycode上加入国家c 在c.code=c2.countrycode上加入countrylanguage c2 查询计划1:

查询计划2:

估计的成本和行不同,最后的散列条件也不同。这是否意味着查询计划器对两个查询没有做相同的事情,或者我走错了方向


谢谢你的帮助

问题不在于联接的顺序,而在于联接条件不同-引用不同的表

在第一个查询中,您将使用city的国家代码加入countrylanguage。在第二种情况下,您使用的是country中的国家代码


对于内部联接,这不会对最终结果产生影响。但是,它显然会影响优化器考虑不同路径的方式。

问题不在于连接的顺序,而在于连接条件不同-参考不同的表

在第一个查询中,您将使用city的国家代码加入countrylanguage。在第二种情况下,您使用的是country中的国家代码

对于内部联接,这不会对最终结果产生影响。但是,它显然会影响优化器考虑不同路径的方式

如前所述,这些查询并不完全相同 这些计划虽然不尽相同,但具有可比性 两个查询都在18毫秒内执行,比较它们几乎是无用的 对结构键、索引、统计信息不足但占用空间足够小的表进行查询时,work\u mem总是会导致哈希联接。 如前所述,这些查询并不完全相同 这些计划虽然不尽相同,但具有可比性 两个查询都在18毫秒内执行,比较它们几乎是无用的 对结构键、索引、统计信息不足但占用空间足够小的表进行查询时,work\u mem总是会导致哈希联接。
@一匹没有名字的马对不起,我按格式添加了查询计划text@a_horse_with_no_name抱歉,我已将查询计划添加为格式化文本
Hash Join  (cost=41.14..484.78 rows=29946 width=161) (actual time=1.472..17.602 rows=30670 loops=1)
  Hash Cond: (city.countrycode = countrylanguage.countrycode)
  ->  Seq Scan on city  (cost=0.00..72.79 rows=4079 width=31) (actual time=0.062..1.220 rows=4079 loops=1)
  ->  Hash  (cost=28.84..28.84 rows=984 width=130) (actual time=1.378..1.378 rows=984 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 172kB
        ->  Hash Join  (cost=10.38..28.84 rows=984 width=130) (actual time=0.267..0.823 rows=984 loops=1)
              Hash Cond: (countrylanguage.countrycode = c.code)
              ->  Seq Scan on countrylanguage  (cost=0.00..15.84 rows=984 width=17) (actual time=0.029..0.158 rows=984 loops=1)
              ->  Hash  (cost=7.39..7.39 rows=239 width=113) (actual time=0.220..0.220 rows=239 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 44kB
                    ->  Seq Scan on country c  (cost=0.00..7.39 rows=239 width=113) (actual time=0.013..0.137 rows=239 loops=1)
Planning Time: 3.818 ms
Execution Time: 18.801 ms

Hash Join  (cost=41.14..312.47 rows=16794 width=161) (actual time=2.415..18.628 rows=30670 loops=1)
  Hash Cond: (city.countrycode = c.code)
  ->  Seq Scan on city  (cost=0.00..72.79 rows=4079 width=31) (actual time=0.032..0.574 rows=4079 loops=1)
  ->  Hash  (cost=28.84..28.84 rows=984 width=130) (actual time=2.364..2.364 rows=984 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 171kB
        ->  Hash Join  (cost=10.38..28.84 rows=984 width=130) (actual time=0.207..1.307 rows=984 loops=1)
              Hash Cond: (c2.countrycode = c.code)
              ->  Seq Scan on countrylanguage c2  (cost=0.00..15.84 rows=984 width=17) (actual time=0.027..0.204 rows=984 loops=1)
              ->  Hash  (cost=7.39..7.39 rows=239 width=113) (actual time=0.163..0.163 rows=239 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 44kB
                    ->  Seq Scan on country c  (cost=0.00..7.39 rows=239 width=113) (actual time=0.015..0.049 rows=239 loops=1)
Planning Time: 1.901 ms
Execution Time: 19.694 ms