【问题标题】:Postgresql not allowing index scan although indexing is there尽管存在索引,但 Postgresql 不允许索引扫描
【发布时间】:2017-07-21 13:02:59
【问题描述】:

我有我制作的表用户

CREATE INDEX user_status_index
  ON public.users
  USING btree
  (status COLLATE pg_catalog."default", "keep_id" COLLATE pg_catalog."default");

当我这样做时

EXPLAIN ANALYZE select * from users where keep_id = 'pop90'

它给了我

"Seq Scan on users (cost=0.00..47284.38 rows=2 width=16) (actual time=960.463..3451.731 rows=2 loops=1)"
"  Filter: (("keep_id")::text = 'pop90'::text)"
"  Rows Removed by Filter: 1271935"
"Planning time: 0.075 ms"
"Execution time: 3451.773 ms"

为什么不进行索引扫描??

如何让它进行索引扫描??

任何帮助都会很明显

【问题讨论】:

    标签: postgresql indexing postgresql-performance


    【解决方案1】:

    您正在使用多列索引。

    使用多列索引时有一些限制。

    创建两个单列索引可能会更好。

    您可以阅读这篇文章: Multi-column Indexes

    多列索引

    虽然 Postgres 能够创建多列索引,但重要的是要了解何时这样做是有意义的。 Postgres 查询计划器能够通过执行位图索引扫描在多列查询中组合和使用多个单列索引。通常,您可以在涵盖查询条件的每一列上创建索引,并且在大多数情况下 Postgres 会使用它们,因此请确保在创建多列索引之前进行基准测试并证明创建多列索引的合理性。与往常一样,索引是有代价的,多列索引只能优化以相同顺序引用索引中列的查询,而多个单列索引为大量查询提供了性能提升。

    但是,在某些情况下,多列索引显然是有意义的。包含 WHERE a = x AND b = y 的查询或仅使用 WHERE a = x 的查询可以使用列 (a, b) 上的索引,但不会由使用 WHERE b = y 的查询使用。因此,如果这与您的应用程序的查询模式相匹配,则值得考虑多列索引方法。另请注意,在这种情况下,仅在 a 上创建索引将是多余的。

    【讨论】:

    • 是的,在我的情况下,有时我们使用 status = 't' 和 keep_id = 'pop90' 但仍然需要 seq 扫描而不是位图索引扫描
    • 你有很多具有相同keep_id的元组吗?计划者可能会决定使用 seq 扫描更好。您是否尝试过在 keep_id 上创建单列索引?
    • 可能是统计信息已过时请运行:vacuum analyze verbose users;
    猜你喜欢
    • 2021-03-19
    • 2020-09-06
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2023-03-14
    相关资源
    最近更新 更多