【问题标题】:limiting the results of a query slows the query限制查询结果会减慢查询速度
【发布时间】:2019-11-22 07:59:44
【问题描述】:

我有一个 PostgreSql 9.6 数据库,用于记录应用程序的调试日志。它包含 1.3 亿条记录。主要字段是使用 GIN 索引的 jsonb 类型。

如果我执行如下查询,它会快速执行:

    select id, logentry from inettklog where
    logentry @> '{"instance":"1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb;

这里是解释分析:

     Bitmap Heap Scan on inettklog  (cost=2938.03..491856.81 rows=137552 width=300) (actual time=10.610..12.644 rows=128 loops=1)
       Recheck Cond: (logentry @> '{"instance": "1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb)
       Heap Blocks: exact=128
       ->  Bitmap Index Scan on inettklog_ix_logentry  (cost=0.00..2903.64 rows=137552 width=0) (actual time=10.564..10.564 rows=128 loops=1)
             Index Cond: (logentry @> '{"instance": "1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb)
     Planning time: 68.522 ms
     Execution time: 12.720 ms
    (7 rows)

但是如果我只是简单地加一个限制,它突然变得很慢:

    select id, logentry from inettklog where
    logentry @> '{"instance":"1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb
    limit 20;

现在需要 20 多秒!

     Limit  (cost=0.00..1247.91 rows=20 width=300) (actual time=0.142..37791.319 rows=20 loops=1)
       ->  Seq Scan on inettklog  (cost=0.00..8582696.05 rows=137553 width=300) (actual time=0.141..37791.308 rows=20 loops=1)
             Filter: (logentry @> '{"instance": "1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb)
             Rows Removed by Filter: 30825572
     Planning time: 0.174 ms
     Execution time: 37791.351 ms
    (6 rows)

以下是包含 ORDER BY 时的结果,即使在设置 enable_seqscan=off 之后也是如此:

没有限制:

set enable_seqscan = off;
set enable_indexscan = on;
select id, date, logentry from inettklog where 
logentry @> '{"instance":"1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb
order by date;

解释分析:

 Sort  (cost=523244.24..523588.24 rows=137600 width=308) (actual time=48.196..48.219 rows=128 loops=1)
   Sort Key: date
   Sort Method: quicksort  Memory: 283kB
   ->  Bitmap Heap Scan on inettklog  (cost=2658.40..491746.00 rows=137600 width=308) (actual time=31.773..47.865 rows=128 loops=1)
         Recheck Cond: (logentry @> '{"instance": "1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb)
         Heap Blocks: exact=128
         ->  Bitmap Index Scan on inettklog_ix_logentry  (cost=0.00..2624.00 rows=137600 width=0) (actual time=31.550..31.550 rows=128 loops=1)
               Index Cond: (logentry @> '{"instance": "1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb)
 Planning time: 0.181 ms
 Execution time: 48.254 ms
(10 rows)

现在当我们添加限制时:

set enable_seqscan = off;
set enable_indexscan = on;
select id, date, logentry from inettklog where 
logentry @> '{"instance":"1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb
order by date
limit 20;

现在需要 90 秒!!!

 Limit  (cost=0.57..4088.36 rows=20 width=308) (actual time=32017.438..98544.017 rows=20 loops=1)
   ->  Index Scan using inettklog_ix_logdate on inettklog  (cost=0.57..28123416.21 rows=137597 width=308) (actual time=32017.437..98544.008 rows=20 loops=1)
         Filter: (logentry @> '{"instance": "1.3.46.670589.11.0.0.11.4.2.0.8743.5.5396.2006120114440692624"}'::jsonb)
         Rows Removed by Filter: 27829853
 Planning time: 0.249 ms
 Execution time: 98544.043 ms
(6 rows)

这一切都非常令人困惑!我希望能够提供一个实用程序来快速查询这个数据库,但这一切都是违反直觉的。

谁能解释发生了什么? 谁能解释一下规则?

【问题讨论】:

    标签: postgresql postgresql-9.6


    【解决方案1】:

    估计值相差甚远。尝试运行ANALYZE,可能会增加default_statistics_target

    由于 PostgreSQL 认为有这么多结果,它认为最好执行顺序扫描并在得到足够的结果后立即停止。

    【讨论】:

      【解决方案2】:

      使用限制而不索引列会减慢速度,因为它会扫描整个表然后给你结果。因此,不要这样做,而是在 logentry 上创建一个索引,然后使用限制运行查询。它会给你更快的结果。

      您可以查看此答案以供参考:PostgreSQL query very slow with limit 1

      【讨论】:

      • 它使用 GIN 索引(如原帖所述)
      猜你喜欢
      • 2011-10-04
      • 2017-12-24
      • 2019-08-13
      • 2015-11-27
      • 2015-09-10
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 2016-12-04
      相关资源
      最近更新 更多