Postgresql - 具有相同列的多个索引
Postgresql - Multiple Indexes with the Same Columns
假设我
- 有一个 table,列为 a、b、c,和 d
- 希望 SELECT 使用这些列的组合进行快速查询
- 期望 a 出现在每个查询中
- 不关心较慢的更新和插入
我应该创建什么索引?以不同顺序创建具有相同列的多个索引是不是一个糟糕的想法?
(a, b)
(a, c)
(a, b, c)
(a, c, b)
...
(a, b, c, d)
(a, d, c, b)
...
这个问题在目前的形式下是无法回答的。影响索引选择和有用性的因素包括:
- 列中数据的基数
- table
中的数据大小
- 数据类型
- 索引的新鲜度
- 查询调整参数
- 是的,索引中列的顺序
综上所述,了解您的 索引将如何执行的唯一方法是使用代表性数据进行测试。
对不起,这里没有捷径。
理论上,如果您完全不关心 update/insert 速度和过大的索引大小(磁盘 space),那么您将需要 WHERE
中使用的所有可能的列组合查询的子句,查询计划器将决定使用哪一个。但是索引是否有用完全取决于 table 数据。
索引列的顺序起着非常重要的作用。列应按基数排序。我们来看例子:
我们有 table 个人(身份证、姓氏、名字、year_of_birth、性别)。
什么索引在这里合适?
- 按名称过滤
我们应该添加哪个索引 - (surname, firstname) 或 (firstname, surname)?正确答案是(surname, firstname),因为如果按姓氏分组,肯定会有更多的记录。
- 按姓名和出生年份过滤
假设我们已经有了 (surname, firstname) 索引。
我们应该把它改成(姓氏,名字,年份)吗?可能会有一些好处,但我对此表示怀疑。对于任何给定的姓氏和名字,可能只有几条不同年龄的记录。关键是,如果我们有几乎唯一的组合(如姓氏 + 名字),那么向索引添加更多列将无济于事,如果有的话。
- 按性别筛选
不需要索引。因为只有两个可能的值:male/female。所以索引不会有效率。
除了索引非常重要之外,我还想说明几点:
- 索引占用额外磁盘space
- 索引影响 update/insert 速度
- 并非所有索引都是高效的(对于一小组记录,顺序扫描速度更快,因为索引查找在性能方面不是免费的)
- 最终,将使用哪个索引由查询计划器决定,这取决于很多因素。有时即使您有索引,它也可能更喜欢顺序扫描。所以你永远不会知道,直到你测试它。
文档中的一个要点:Combining Multiple Indexes
In all but the simplest applications, there are various combinations of indexes that might be useful, and the database developer must make trade-offs to decide which indexes to provide. Sometimes multicolumn indexes are best, but sometimes it's better to create separate indexes and rely on the index-combination feature.
假设我
- 有一个 table,列为 a、b、c,和 d
- 希望 SELECT 使用这些列的组合进行快速查询
- 期望 a 出现在每个查询中
- 不关心较慢的更新和插入
我应该创建什么索引?以不同顺序创建具有相同列的多个索引是不是一个糟糕的想法?
(a, b)
(a, c)
(a, b, c)
(a, c, b)
...
(a, b, c, d)
(a, d, c, b)
...
这个问题在目前的形式下是无法回答的。影响索引选择和有用性的因素包括:
- 列中数据的基数
- table 中的数据大小
- 数据类型
- 索引的新鲜度
- 查询调整参数
- 是的,索引中列的顺序
综上所述,了解您的 索引将如何执行的唯一方法是使用代表性数据进行测试。 对不起,这里没有捷径。
理论上,如果您完全不关心 update/insert 速度和过大的索引大小(磁盘 space),那么您将需要 WHERE
中使用的所有可能的列组合查询的子句,查询计划器将决定使用哪一个。但是索引是否有用完全取决于 table 数据。
索引列的顺序起着非常重要的作用。列应按基数排序。我们来看例子:
我们有 table 个人(身份证、姓氏、名字、year_of_birth、性别)。 什么索引在这里合适?
- 按名称过滤
我们应该添加哪个索引 - (surname, firstname) 或 (firstname, surname)?正确答案是(surname, firstname),因为如果按姓氏分组,肯定会有更多的记录。
- 按姓名和出生年份过滤
假设我们已经有了 (surname, firstname) 索引。 我们应该把它改成(姓氏,名字,年份)吗?可能会有一些好处,但我对此表示怀疑。对于任何给定的姓氏和名字,可能只有几条不同年龄的记录。关键是,如果我们有几乎唯一的组合(如姓氏 + 名字),那么向索引添加更多列将无济于事,如果有的话。
- 按性别筛选
不需要索引。因为只有两个可能的值:male/female。所以索引不会有效率。
除了索引非常重要之外,我还想说明几点:
- 索引占用额外磁盘space
- 索引影响 update/insert 速度
- 并非所有索引都是高效的(对于一小组记录,顺序扫描速度更快,因为索引查找在性能方面不是免费的)
- 最终,将使用哪个索引由查询计划器决定,这取决于很多因素。有时即使您有索引,它也可能更喜欢顺序扫描。所以你永远不会知道,直到你测试它。
文档中的一个要点:Combining Multiple Indexes
In all but the simplest applications, there are various combinations of indexes that might be useful, and the database developer must make trade-offs to decide which indexes to provide. Sometimes multicolumn indexes are best, but sometimes it's better to create separate indexes and rely on the index-combination feature.