【问题标题】:Postgres is not using partial indexPostgres 没有使用部分索引
【发布时间】:2023-03-06 04:10:01
【问题描述】:

我尝试使用部分索引对表中的 id 进行计数,但性能非常低

SELECT COUNT("refuel_request"."refuel_request_id") as "count" 
FROM "refuel_request" 
WHERE "refuel_request"."refuel_request_status_id" 
IN ('1','2','3')

我创建索引

CREATE INDEX idx_refuel_request_status_id10 ON refuel_request (refuel_request_status_id)
WHERE "refuel_request"."refuel_request_status_id" 
IN ('1','2','3')

你能解释一下我做错了什么吗?

解释

[
 {
"Plan": {
  "Node Type": "Seq Scan",
  "Parallel Aware": false,
  "Relation Name": "refuel_request",
  "Alias": "refuel_request",
  "Startup Cost": 0,
  "Total Cost": 160442.88,
  "Plan Rows": 4700100,
  "Plan Width": 16,
  "Filter": "(refuel_request_status_id = ANY ('{1,2,3}'))"
   }
  }
 ]

解释(分析,缓冲区)

解释(分析、格式化文本)

Finalize Aggregate  (cost=114931.68..114931.69 rows=1 width=8) (actual time=570.019..570.020 rows=1 loops=1)
  ->  Gather  (cost=114931.47..114931.68 rows=2 width=8) (actual time=569.735..575.504 rows=3 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        ->  Partial Aggregate  (cost=113931.47..113931.48 rows=1 idth=8) (actual time=528.094..528.094 rows=1 loops=3)
              ->  Parallel Seq Scan on refuel_request cost=0.00..109035.53 rows=1958375 width=16) (actual time=0.070..452.908 rows=1566700 loops=3)
                    Filter: (refuel_request_status_id = ANY ('{1,2,3}'))
Planning Time: 0.665 ms
Execution Time: 575.538 ms

【问题讨论】:

  • 也许你的表太小了 - 计划者选择并行的 seq 扫描,因为这种方法现在有情人成本来为你的表做这个查询。其他选择是-您的子句几乎涵盖了整个表格....
  • 我的表格中有 400 万个元素
  • 当索引不是部分时检查相同的查询 - 如果计划没有索引并且条件中只有 3 个值 - 也许使用联合查询将使用非部分索引 ....
  • @areklipno 我尝试使用 CREATE INDEX idx_refuel_request_status_id ON refuel_request (refuel_request_status_id) 。但它不起作用
  • @a_horse_with_no_name 添加文本格式

标签: sql postgresql indexing explain


【解决方案1】:

在顺序扫描中过滤器不会删除任何行,因此似乎表中的所有行都有refuel_request_status_id 等于'1''2''3'。所以索引中的WHERE 条件没有任何区别。

您可以尝试使用enable_seqscan = off 来查看 PostgreSQL 是否做出了正确的选择。如果没有,可能random_page_cost 没有为您的硬件正确设置。

如果事实证明顺序扫描确实是最快的方法,那么您无法加快查询速度:您可以获得更快的存储空间或更多的 RAM 来缓存表。

Counting is slow business.

【讨论】:

  • enable_seqscan = off 将执行时间增加到 4 秒(您对此查询的更新性能有什么想法吗?
  • 仅索引扫描我错了 - 请参阅我更新的答案。
猜你喜欢
  • 2012-09-06
  • 2019-10-02
  • 2021-12-29
  • 2020-12-24
  • 2015-03-14
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多