为什么限制10比限制100慢?

时间:2018-05-30 08:18:53

标签: database postgresql

sql limit 10 offset 0:

 EXPLAIN (analyze,buffers) SELECT
        jdry.c_bh AS rybh, 
        jcyq.c_bh,
        jdry.c_xm,
        jdry.c_jdrybm,
        jcyq.c_jdsbm,
        jcyq.c_bmbm,
        jdry.c_fq,
        jdry.c_fj
    FROM
        db_ggfw.T_JDRY jdry,
        db_szgl.T_JCYQ jcyq
    WHERE
        jdry.c_jdrybm = jcyq.c_jdrybm
    AND jcyq.c_sfyx <> '0'
    AND jcyq.c_dqspjg IS NULL
    AND jcyq.c_lx = '01'
    AND jcyq.c_dqspzt = '01'
    AND jcyq.c_jdsbm = '530104'
    ORDER BY
        dt_rssj DESC
    LIMIT 10 OFFSET 0

此执行计划的结果:

    Limit  (cost=0.84..2211.77 rows=10 width=124) (actual time=800.415..3228.545 rows=3 loops=1)
      Buffers: shared hit=729261
      ->  Nested Loop  (cost=0.84..126023.71 rows=570 width=124) (actual time=800.412..3228.534 rows=3 loops=1)
            Buffers: shared hit=729261
            ->  Index Scan using i_T_JDRY_dt_rssj on T_JDRY jdry  (cost=0.42..21059.54 rows=150163 width=73) (actual time=0.022..282.385 rows=150068 loops=1)
                  Buffers: shared hit=147487
            ->  Index Scan using i_jcyq_rybh on T_JCYQ jcyq  (cost=0.42..0.69 rows=1 width=68) (actual time=0.019..0.019 rows=0 loops=150068)
                  Index Cond: ((c_jdrybm)::text = (jdry.c_jdrybm)::text)
                  Filter: ((c_dqspjg IS NULL) AND ((c_sfyx)::text <> '0'::text) AND ((c_lx)::text = '01'::text) AND ((c_dqspzt)::text = '01'::text) AND ((c_jdsbm)::text = '530104'::text))
                  Rows Removed by Filter: 1
                  Buffers: shared hit=581774
    Planning time: 0.896 ms
    Execution time: 3228.649 ms

限制100偏移0:

    EXPLAIN (analyze,buffers) SELECT
        jdry.c_bh AS rybh,
        jcyq.c_bh,
        jdry.c_xm,
        jdry.c_jdrybm,
        jcyq.c_jdsbm,
        jcyq.c_bmbm,
        jdry.c_fq,
        jdry.c_fj
    FROM
        db_ggfw.T_JDRY jdry,
        db_szgl.T_JCYQ jcyq
    WHERE
        jdry.c_jdrybm = jcyq.c_jdrybm
    AND jcyq.c_sfyx <> '0'
    AND jcyq.c_dqspjg IS NULL
    AND jcyq.c_lx = '01'
    AND jcyq.c_dqspzt = '01'
    AND jcyq.c_jdsbm = '530104'
    ORDER BY
        dt_rssj DESC
    **LIMIT 100 OFFSET 0**

此执行计划的结果:

    Limit  (cost=12365.88..12366.13 rows=100 width=124) (actual time=63.142..63.144 rows=3 loops=1)
      Buffers: shared hit=8810
      ->  Sort  (cost=12365.88..12367.31 rows=570 width=124) (actual time=63.139..63.139 rows=3 loops=1)
            Sort Key: jdry.dt_rssj DESC
            Sort Method: quicksort  Memory: 25kB
            Buffers: shared hit=8810
            ->  Gather  (cost=1000.42..12344.10 rows=570 width=124) (actual time=20.764..63.104 rows=3 loops=1)
                  Workers Planned: 2
                  Workers Launched: 2
                  Buffers: shared hit=8810
                  ->  Nested Loop  (cost=0.42..11287.10 rows=238 width=124) (actual time=43.906..57.953 rows=1 loops=3)
                        Buffers: shared hit=8524
                        ->  Parallel Seq Scan on T_JCYQ jcyq  (cost=0.00..9597.27 rows=238 width=68) (actual time=43.869..57.862 rows=1 loops=3)
                              Filter: ((c_dqspjg IS NULL) AND ((c_sfyx)::text <> '0'::text) AND ((c_lx)::text = '01'::text) AND ((c_dqspzt)::text = '01'::text) AND ((c_jdsbm)::text = '530104'::text))
                              Rows Removed by Filter: 43409
                              Buffers: shared hit=8512
                        ->  Index Scan using i_jdry_rybm_unique on T_JDRY jdry  (cost=0.42..7.09 rows=1 width=73) (actual time=0.061..0.063 rows=1 loops=3)
                              Index Cond: ((c_jdrybm)::text = (jcyq.c_jdrybm)::text)
                              Buffers: shared hit=12
    Planning time: 1.127 ms
    Execution time: 66.655 ms

限制10偏移0:T_jdry使用索引i_T_JDRY_dt_rssj。
limit 100 offset 0:t_jcyq seq_scan。

使用限制10和100时执行计划不同,限制10非常慢。

当我删除限制时,SQL也很快。 当我删除索引i_T_JDRY_dt_rssj时,它非常快。

1 个答案:

答案 0 :(得分:0)

EXPLAIN  analyze
SELECT
    jdry.c_bh AS rybh,
    jcyq.c_bh,
    jdry.c_xm,
    jdry.c_jdrybm,
    jcyq.c_jdsbm,
    jcyq.c_bmbm,
    jdry.c_fq,
    jdry.c_fj
FROM
(select * from db_szgl.T_JCYQ jcyq1
WHERE jcyq1.c_sfyx <> '0'
AND jcyq1.c_dqspjg IS NULL
AND jcyq1.c_lx = '01'
AND jcyq1.c_dqspzt = '01'
AND jcyq1.c_jdsbm = '530104' order by dt_gxsj)
jcyq join 
    db_ggfw.T_JDRY jdry
on
    jdry.c_jdrybm = jcyq.c_jdrybm
ORDER BY jdry.dt_rssj DESC
LIMIT 10 OFFSET 0

Limit  (cost=16664.88..16664.90 rows=10 width=124) (actual time=70.415..70.417 rows=3 loops=1)
  ->  Sort  (cost=16664.88..16666.30 rows=570 width=124) (actual time=70.413..70.413 rows=3 loops=1)
        Sort Key: jdry.dt_rssj DESC
        Sort Method: quicksort  Memory: 25kB
        ->  Nested Loop  (cost=12598.78..16652.56 rows=570 width=124) (actual time=70.355..70.396 rows=3 loops=1)
              ->  Sort  (cost=12598.36..12599.78 rows=570 width=7836) (actual time=70.295..70.296 rows=3 loops=1)
                    Sort Key: jcyq1.dt_gxsj
                    Sort Method: quicksort  Memory: 25kB
                    ->  Gather  (cost=1000.00..10654.27 rows=570 width=7836) (actual time=27.578..70.259 rows=3 loops=1)
                          Workers Planned: 2
                          Workers Launched: 2
                          ->  Parallel Seq Scan on T_JCYQ jcyq1  (cost=0.00..9597.27 rows=238 width=7836) (actual time=47.349..62.938 rows=1 loops=3)
                                Filter: ((c_dqspjg IS NULL) AND ((c_sfyx)::text <> '0'::text) AND ((c_lx)::text = '01'::text) AND ((c_dqspzt)::text = '01'::text) AND ((c_jdsbm)::text = '530104'::text))
                                Rows Removed by Filter: 43410
              ->  Index Scan using i_jdry_rybm_unique on T_JDRY jdry  (cost=0.42..7.09 rows=1 width=73) (actual time=0.026..0.026 rows=1 loops=3)
                    Index Cond: ((c_jdrybm)::text = (jcyq1.c_jdrybm)::text)
Planning time: 2.276 ms
Execution time: 74.295 ms