• 对PostgreSQL Nested Loop 执行计划的初步学习


    开始

    伪代码如下:

    for (i = 0; i < length(outer); i++)
      for (j = 0; j < length(inner); j++)
        if (outer[i] == inner[j])
          output(outer[i], inner[j]);

    就是个双层循环。

    实际运行一下:

    建表:

    postgres=# CREATE TEMPORARY TABLE sample1 (id, junk) AS
    postgres-# SELECT oid, repeat('x',250)
    postgres-# FROM pg_proc
    postgres-# ORDER BY random(); -- add rows in random order;
    SELECT 2491
    postgres=# 
    postgres=# CREATE TEMPORARY TABLE sample2 (id, junk) AS
    postgres-# SELECT oid, repeat('x',250)
    postgres-# FROM pg_class
    postgres-# ORDER BY random();
    SELECT 298
    postgres=# 

    运行:

    postgres=# EXPLAIN analyze SELECT sample2.junk
    FROM sample1 JOIN sample2 ON (sample1.id = sample2.id)
    WHERE sample1.id = 33;
                                                      QUERY PLAN                                                   
    ---------------------------------------------------------------------------------------------------------------
     Nested Loop  (cost=0.00..271.44 rows=399 width=32) (actual time=0.120..0.120 rows=0 loops=1)
       ->  Seq Scan on sample1  (cost=0.00..235.99 rows=57 width=4) (actual time=0.087..0.118 rows=1 loops=1)
             Filter: (id = 33::oid)
             Rows Removed by Filter: 2490
       ->  Materialize  (cost=0.00..30.48 rows=7 width=36) (actual time=0.000..0.000 rows=0 loops=1)
             ->  Seq Scan on sample2  (cost=0.00..30.45 rows=7 width=36) (actual time=0.000..0.000 rows=0 loops=1)
                   Filter: (id = 33::oid)
                   Rows Removed by Filter: 298
     Total runtime: 0.234 ms
    (9 rows)

    如果和使用 with 子句相比,还是快一些:

    postgres=# explain analyze                    
    WITH testsample AS (
       select * from sample1 where sample1.id=33
    )
    SELECT sample2.junk
    FROM testsample JOIN sample2 ON (testsample.id = sample2.id)
    ;
                                                       QUERY PLAN                                                    
    -----------------------------------------------------------------------------------------------------------------
     Hash Join  (cost=237.84..274.35 rows=421 width=32) (actual time=0.387..0.387 rows=0 loops=1)
       Hash Cond: (sample2.id = testsample.id)
       CTE testsample
         ->  Seq Scan on sample1  (cost=0.00..235.99 rows=57 width=36) (actual time=0.174..0.284 rows=1 loops=1)
               Filter: (id = 33::oid)
               Rows Removed by Filter: 2490
       ->  Seq Scan on sample2  (cost=0.00..26.76 rows=1476 width=36) (actual time=0.009..0.040 rows=298 loops=1)
       ->  Hash  (cost=1.14..1.14 rows=57 width=4) (actual time=0.301..0.301 rows=1 loops=1)
             Buckets: 1024  Batches: 1  Memory Usage: 1kB
             ->  CTE Scan on testsample  (cost=0.00..1.14 rows=57 width=4) (actual time=0.177..0.288 rows=1 loops=1)
     Total runtime: 0.489 ms
    (11 rows)
    
    postgres=# 

    不过这只是一个实验,要是真的简化起来,不就是这样了么?

    postgres=# explain analyze SELECT sample2.junk
    from sample2 WHERE sample2.id=33;
                                                QUERY PLAN                                             
    ---------------------------------------------------------------------------------------------------
     Seq Scan on sample2  (cost=0.00..30.45 rows=7 width=32) (actual time=0.042..0.042 rows=0 loops=1)
       Filter: (id = 33::oid)
       Rows Removed by Filter: 298
     Total runtime: 0.147 ms
    (4 rows)
    
    postgres=# 

    结束

  • 相关阅读:
    RegularExpressions(正则表达式)
    IntelliJ Idea工具使用
    JavaScript总结
    Ajax技术基础
    配置Nginx作为反向代理服务器
    SpringBoot下的Dubbo和Zookeeper整合
    springSecurity初识练气初期
    Spring Security拦截器加载流程分析练气中期
    Spring Security认证流程分析练气后期
    springBoot整合spring security+JWT实现单点登录与权限管理前后端分离筑基中期
  • 原文地址:https://www.cnblogs.com/gaojian/p/2762028.html
Copyright © 2020-2023  润新知