B-tree 索引:
适用场景:范围查询、索引等值查询、类型排序操作。详解

特点:适用于大部分查询场景,索引是类型 PostgreSQL 默认的索引类型。
哈希索引:
适用场景:等值查询,详解对于频繁的索引等值查询有性能优势。
特点:不支持范围查询和排序操作,类型大小写敏感。详解
GIN 索引:
适用场景:全文搜索、索引数组包含查询、类型JSONB 数据类型查询。详解
特点:支持对复杂查询条件的索引优化,如使用数组和 JSONB 类型的类型数据。
GiST 索引:
适用场景:空间数据类型(如几何形状)、详解全文搜索。
特点:支持多种数据类型的复杂查询优化。
BRIN 索引:
适用场景:大表的列存储,适合有序数据。
特点:适合于大数据量表的存储,减少索引的存储空间。
Partial 索引:
适用场景:对表中特定子集数据的查询优化。
特点:只对表中满足条件的行建立索引,亿华云计算节省存储空间和提高查询性能。
SP-GiST 索引:
适用场景:空间数据类型(如几何形状)、全文搜索。
特点:支持多种数据类型的复杂查询优化。
bloom 索引:
适用场景:适用于高基数列的等值查询优化。
特点:布隆过滤器索引,适合于检查元素是否属于一个集合,但可能存在误报(false positive),因此需要使用实际数据再次验证
只有B 树、GiST、GIN 和 BRIN索引类型支持多列键索引。索引是否可以有多个键列与是否可以向索引中添加列无关。每个索引最多可以有32列,包括键列
复制示例 CREATE INDEX test2_mm_idx ON test2 (major, minor);1.2.多列B 树索引可以与涉及索引任意子集的查询条件一起使用,但在约束条件应用于前导(最左边)列时效率最高。
对于多列索引,等式约束应用于前导列,并且在第一个没有等式约束的列上应用不等式约束,这些约束将限制扫描索引的部分。
对于后续列的约束也会在索引中检查,这样可以减少对实际表的访问次数,但并不会减少需要扫描的索引部分。香港云服务器
多列GiST索引可以与涉及任意子集的查询条件一起使用。对额外列的条件限制会限制索引返回的条目,但第一列上的条件最为重要,影响需要扫描的索引部分。
多列GIN索引可以与涉及任意子集的查询条件一起使用。与B 树或GiST不同的是,无论查询条件使用哪些索引列,索引搜索的效果都是相同的。
多列BRIN索引可以与涉及任意子集的查询条件一起使用。与GIN类似,与B 树或GiST不同的是,无论查询条件使用哪些索引列,索引搜索的效果都是相同的。
在单个表上,多个BRIN索引通常没有必要,除非需要使用不同的IT技术网存储参数(pages_per_range)。
总结:
每种索引类型对多列索引的支持和效果略有不同,应根据具体查询模式、数据类型和性能需求选择合适的索引类型。
多列索引应谨慎使用,因为单列索引通常已经足够提供良好的性能,并节省存储空间和维护成本。
对于超过三列的索引,除非表的使用非常特殊,否则可能不会有帮助。
目前 PostgreSQL 支持的索引类型中,只有 B 树能够产生排序的输出结果 — 其他索引类型返回的匹配行的顺序是未指定的,依赖于具体实现。
默认情况下,B 树索引以升序存储条目,空值排在最后。这意味着对于列 x 的索引正向扫描会生成满足 ORDER BY x 或 ORDER BY x ASC NULLS LAST 的输出。索引也可以反向扫描,生成满足 ORDER BY x DESC 或 ORDER BY x DESC NULLS FIRST 的输出。
在创建 B 树索引时,可以通过包括 ASC、DESC、NULLS FIRST 和 NULLS LAST 选项来调整索引的排序顺序。
复制例如: CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST); CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);1.2.3.在单列索引中,这些选项可能看起来有些冗余,但在多列索引中它们非常有用。考虑一个两列索引 (x, y):正向扫描可以满足 ORDER BY x, y,反向扫描可以满足 ORDER BY x DESC, y DESC。但如果应用程序频繁需要使用 ORDER BY x, y ASC,则普通索引无法提供此顺序,但可以通过定义为 (x ASC, y ASC) 或 (x DESC, y ASC) 来实现。
显然,具有非默认排序顺序的索引是一种相对特殊的功能,但有时它们可以为某些查询带来巨大的性能提升。是否值得维护这样的索引取决于查询中需要特定排序顺序的频率。
在唯一约束列上手动创建索引通常是多余的,因为系统会自动创建该索引。手动创建索引可能会导致重复,不建议这样做。
索引列不必只是基础表的一列,还可以是从表的一列或多列计算得出的函数或标量表达式。此功能对于根据计算结果快速访问表非常有用。
索引表达式的性能
索引表达式的维护成本较高,因为对于每次行插入和非 HOT 更新,必须计算派生表达式。然而,在索引搜索期间,不需要重新计算索引表达式,因为它们已经存储在索引中。索引表达式适用于检索速度比插入和更新速度更重要的场景。假设你在数据库中存储 Web 服务器访问日志。大多数访问来自于你组织的 IP 地址范围,但有些来自于其他地方(比如员工使用拨号连接)。如果你的 IP 地址搜索主要针对外部访问,那么你可能不需要索引与你组织子网对应的 IP 范围。
复制CREATE INDEX access_log_client_ip_ix ON access_log (client_ip) WHERE NOT (client_ip > inet 192.168.100.0 AND client_ip < inet 192.168.100.255);1.2.3.如果您的表同时包含计费订单和未计费订单,其中未计费订单仅占总表的一小部分,但这些行是访问次数最多的行,则可以通过仅在未计费行上创建索引来提高性能。创建索引的命令如下所示:
复制CREATE INDEX orders_unbilled_index ON orders (order_nr) WHERE billed is not true;1.2.假设我们有一个描述测试结果的表格。我们希望确保给定的主题和目标组合只有一个“成功”条目,但可能存在任意数量的“不成功”条目。这是一种方法:
复制CREATE TABLE tests ( subject text, target text, success boolean, faill boolean ... ); CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) WHERE success;1.2.3.4.5.6.7.8.9.10.11.当成功的测试很少而失败的测试很多时,这是一种特别有效的方法。也可以通过创建具有限制的唯一部分索引,在列中只允许一个 null。IS NULL
在数据库中,不应该通过创建大量非重叠的部分索引来替代分区。例如,像下面这样创建一组部分索引:
复制CREATE INDEX mytable_cat_1 ON mytable (data) WHERE category = 1; CREATE INDEX mytable_cat_2 ON mytable (data) WHERE category = 2; CREATE INDEX mytable_cat_3 ON mytable (data) WHERE category = 3; ... CREATE INDEX mytable_cat_N ON mytable (data) WHERE category = N;1.2.3.4.5.这种做法是不明智的!更好的方式是使用一个单独的非部分索引,如下所示:
复制CREATE INDEX mytable_cat_data ON mytable (category, data);1.这种部分索引需要预先确定共同的值,因此最适合用于数据分布不会经常变化的情况。这样的索引偶尔需要重新创建以适应新的数据分布,但这会增加维护工作量。
使用 EXPLAIN 命令可以分析单个查询的执行计划,包括查询是否使用了索引以及使用了哪些索引。
这对于了解实际查询工作负载中索引的使用情况非常重要。
在优化索引前,始终先运行 ANALYZE 命令。这个命令用于收集关于表中值分布的统计信息。
统计信息对于评估查询返回行数的分布是必要的,优化器需要根据这些信息为每个可能的查询计划分配合理的成本。
如果没有实际的统计信息,优化器会使用默认值,这几乎肯定是不准确的。
在设置索引时,使用真实数据进行实验可以告诉你针对测试数据集需要哪些索引。
使用非常小的测试数据集通常是不可取的,因为这可能无法准确反映真实数据的查询性能。
当索引未被使用时,可以通过运行时参数强制其使用,例如关闭顺序扫描 (enable_seqscan) 或嵌套循环连接 (enable_nestloop)。
如果强制使用索引后确实使用了索引,那么有两种可能性:系统正确地判断索引不适合使用,或者查询计划的成本估算不符合实际情况。
使用 EXPLAIN ANALYZE 命令可以获取查询的详细执行统计信息,包括实际执行时间和成本估算。
这对于评估查询计划的实际性能表现非常有用,特别是在调整查询计划的成本估算时。
如果成本估算不准确,可以通过调整运行时参数来调整计划节点的成本估算,或者通过优化统计信息收集参数来提高查询选择性估算的准确性。
总体而言,优化索引的过程涉及实验、分析和调整,需要根据具体的查询工作负载和实际数据来进行。通过这些步骤,可以更有效地提升 PostgreSQL 数据库的查询性能和响应速度。
综上所述,每种索引类型在不同的场景下都有其优势和劣势。正确选择和设计索引是优化 PostgreSQL 数据库性能的关键一步。
相关文章: