【问题标题】:Postgresql - Multiple Indexes with the Same ColumnsPostgresql - 具有相同列的多个索引
【发布时间】:2017-09-08 19:34:57
【问题描述】:

假设我

  • 有一个包含 abcd 列的表
  • 希望包含这些列组合的 SELECT 查询速度极快
  • 希望 a 出现在每个查询中
  • 不要关心缓慢的更新和插入

我应该创建哪些索引,并且以不同的顺序创建具有相同列的多个索引是一个可怕的想法?

(a, b)

(a, c)

(a, b, c)

(a, c, b)

...

(a, b, c, d)

(a, d, c, b)

...

【问题讨论】:

  • a,b,c,d 是什么类型?
  • 一个是整数,其余是varchar
  • Postgres 可以为单个查询组合同一张表上的多个索引。所以我会为每一列尝试一个索引,看看你使用的通常查询的效率如何。如果a 列上的条件已经充分减少了结果中的行数,则所有列上的单个 B 树也可能就足够了。您可能还想在所有列上尝试 BRIN indexbloom filter index

标签: database postgresql indices postgresql-9.5


【解决方案1】:

这个问题目前的形式是无法回答的。影响索引选择和有用性的因素包括:

  • 列中数据的基数
  • 表中数据的大小
  • 数据类型
  • 索引的新鲜度
  • 查询调优参数
  • 是的,索引中列的顺序

话虽如此,了解您的索引将如何执行的唯一方法是使用代表性数据进行测试。 抱歉,这里没有捷径。

【讨论】:

    【解决方案2】:

    理论上,如果您完全不关心更新/插入速度和过多的索引大小(磁盘空间),那么您将需要查询的WHERE 子句中使用的所有可能的列组合,并且查询计划器将决定使用哪一个。但是索引是否有用取决于表数据。

    索引列的顺序起着非常重要的作用。列应按基数排序。我们来看例子:

    我们有一张人员表(id、surname、firstname、year_of_birth、sex)。 这里适合什么索引?

    1. 按名称过滤

    我们应该添加哪个索引 - (surname, firstname) 或 (firstname, surname)?正确答案是 (surname, firstname),因为如果按姓氏对记录进行分组,记录数肯定会更高。

    1. 按姓名和出生年份过滤

    假设我们已经有 (surname, firstname) 索引。 我们应该将其更改为(姓、名、年)吗?可能会有一些好处,但我对此表示怀疑。对于任何给定的姓氏和名字,可能只有几条不同年龄的记录。关键是,如果我们有几乎唯一的组合(例如姓氏 + 名字),那么向索引添加更多列将无济于事。

    1. 按性别过滤

    不需要索引。因为只有两个可能的值:男/女。所以索引不会有效率。


    除了索引非常重要和重要之外,我还想说明几点:

    • 索引占用额外的磁盘空间
    • 索引会影响更新/插入速度
    • 并非所有索引都高效(对于一小部分记录,顺序扫描更快,因为索引查找在性能方面并不是免费的)
    • 最终,要使用哪个索引是由查询计划器决定的,这取决于很多因素。有时即使您有索引,它也可能更喜欢顺序扫描。因此,除非您对其进行测试,否则您永远不会知道。

    文档中的一个要点:Combining Multiple Indexes

    在除最简单的应用程序之外的所有应用程序中,都有可能有用的各种索引组合,数据库开发人员必须做出权衡来决定提供哪些索引。有时多列索引是最好的,但有时最好创建单独的索引并依赖索引组合功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 1970-01-01
      • 2015-04-12
      • 2011-01-25
      相关资源
      最近更新 更多