【问题标题】:Erratic indexed query performance in PostgreSQLPostgreSQL 中不稳定的索引查询性能
【发布时间】:2013-01-16 01:43:43
【问题描述】:

需要有关 PostgreSQL 中查询性能的帮助。它似乎与索引有关。

这个查询:

  • 根据type过滤
  • timestamp 排序,升序:

SELECT * FROM the_table WHERE type = 'some_type' ORDER BY timestamp LIMIT 20

索引:

 CREATE INDEX the_table_timestamp_index ON the_table(timestamp);

 CREATE INDEX the_table_type_index ON the_table(type);

type 字段的值只是大约 11 个不同字符串之一。
问题是查询似乎在 O(log n) 时间内执行,大多数时候只需要几毫秒,除了 type 的某些值需要几分钟才能运行。

在这些示例查询中,第一个查询仅需几毫秒即可运行,而第二个查询则需要 30 多分钟:

SELECT * FROM the_table WHERE type = 'goq' ORDER BY timestamp LIMIT 20
SELECT * FROM the_table WHERE type = 'csp' ORDER BY timestamp LIMIT 20

我有大约 90% 的把握怀疑我们拥有的索引不是正确的。我认为,在阅读this similar question about index performance 之后,我们最需要的是一个综合索引,超过typetimestamp

我运行的查询计划在这里:

  1. Expected performance, type-specific index (i.e. new index with the type = 'csq' in the WHERE clause)。
  2. Slowest, problematic case, indexes as described above.
  3. Fast case, same indexes as above.

非常感谢您的帮助!任何指针将不胜感激!

【问题讨论】:

  • 索引的大小是多少?以及数据集的大小?

标签: sql performance postgresql indexing


【解决方案1】:

索引可用于where 子句或order by 子句。使用索引thetable(type, timestamp),则可以对两者使用相同的索引。

我的猜测是 Postgres 正在根据它收集的统计数据来决定使用哪个索引。当它使用索引作为 where 然后尝试排序时,你会得到非常糟糕的性能。

这只是一个猜测,但值得创建上述索引以查看是否可以解决性能问题。

【讨论】:

    【解决方案2】:

    解释输出都使用时间戳索引。这可能是因为类型列的基数太低,因此对该列的索引进行扫描与表扫描一样昂贵。

    要创建的复合索引应该是:

    create index comp_index on the_table ("timestamp", type)
    

    按这个顺序。

    【讨论】:

    • 太棒了!那么索引中列的顺序有区别吗?
    • @JuanCarlosCoto 。 . .事实上,顺序确实有所作为。通过将timestamp 放在首位,引擎无法将索引用于where 子句。各种类型将分散在整个索引中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    相关资源
    最近更新 更多