【问题标题】:Designing an index for a postgres query为 postgres 查询设计索引
【发布时间】:2012-06-05 21:35:42
【问题描述】:

我们有一个从主从简单模式中检索一些数据的查询。 WHERE 子句如下所示:

-- These are just random numbers
Where ticket.type_id in ( 2, 3, 4, 5, 7 ) and
      (
         ticket.color_id is null or
         ticket.color_id in ( 1, 2 , 8 )
      )

我们已经在列中有索引:ticket.type_id 和 ticket.color_id,无论如何,QUERY EXPLAIN ANALYZE 仍然向我们显示 Postgresql 正在进行顺序扫描以满足查询。

这个查询在系统中非常重要且经常出现,所以我们想专门为这种情况创建一个索引。

什么索引可以解决这种情况?

【问题讨论】:

  • 如果你只做Where ticket.type_id in ( 2, 3, 4, 5, 7 )会使用索引吗?
  • 它可能认为对表进行顺序扫描比为 IN 子句中的每个 ID 重新扫描索引要快。除非表非常大并且指定的type_ids 是数据的一小部分,否则可能是对的。
  • 在这种情况下,是一个大表(数百万条记录),有什么额外的想法吗?
  • 你能把EXPLAIN粘贴到Where ticket.type_id in ( 2, 3, 4, 5, 7 )吗?
  • 请提供整个查询。难道只是一个简单的WHERE?有HAVING吗? ORDER BY? LIMIT?连接了多少张表?

标签: database performance postgresql indexing profiling


【解决方案1】:

首先,检查索引是否真的可以帮助您。在调用查询之前关闭序列扫描以强制使用索引:

SET ENABLE_SEQSCAN TO OFF;

查询运行后:

SET ENABLE_SEQSCAN TO ON;

重新启用序列扫描。如果这显示没有性能改进,Postgres 已经在选择正确的执行计划(序列扫描)。我会为整个查询运行explain analyze <query>,同时开启和关闭序列扫描。

您是否在相关表格上运行了vacuum analyze?规划器可能没有针对您的查询的正确或当前统计信息。

【讨论】:

    【解决方案2】:

    不太确定 - 但我认为 null 正在变得越来越好..

    可能是这样一个奇怪的结构

    Where ticket.type_id in ( 2, 3, 4, 5, 7 ) and
          (
             nvl(ticket.color_id,1) in ( 1, 2 , 8 )
          )
    

    【讨论】:

    • Nvl() 是一个 Oracle 函数。使用 coalesce(),但这不能使用索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    • 1970-01-01
    • 2013-05-31
    • 2014-03-24
    • 2017-09-12
    • 1970-01-01
    相关资源
    最近更新 更多