PostgreSQL 索引的重要要点

news/2024/11/24 23:31:49/

       PostgreSQL官方文档对索引的定义,非常简单明了:“索引是提高数据库性能的常见方式。索引使得数据库服务器能够比没有索引时更快地查找和检索特定行。但索引也会增加整个数据库系统的开销,因此应该合理使用。

        这个定义中的关键是最后一个词“合理”。索引是有益的,它们可以提高查询的性能。但这并不意味着我们要为每个查询和每个列创建索引。需要记住的是,虽然索引确实提高了性能,但它们需要维护,这也是一种开销。

        在处理PostgreSQL性能时,以下是我发现的一些关于PostgreSQL索引的重要要点,这些要点将帮助设计增强性能的索引,其中性能收益超过维护开销:

1. 在将新的/修改的索引部署到生产环境时,使用CREATE INDEX命令的CONCURRENTLY选项。这将允许数据库上的“写”操作无缝进行。需要密切监视部署过程中的条件,并注意,部署失败可能会导致无效索引,需要手动删除。

2. 在定义中有多个列的索引必须尽量少用。PostgreSQL查询规划器将主要的“过滤条件”作为索引的前导列,因此定义中的其他列虽然可能用于不等式比较或获取数据,但通常更多是维护开销,而不是性能收益。

3. 我们可以在索引定义中使用“WHERE子句”设计部分索引。这样可以节省空间和时间,但需要非常谨慎地使用,只有当我们绝对确定条件与查询直接或算术上相关时,或者索引可以成为维护开销而没有性能收益时。

4. 如果工作负载包含有时仅涉及列x,有时仅涉及列y,有时涉及列x和y的查询,可以选择在x和y上创建两个单独的索引,依靠索引组合来处理使用两个列的查询。这比在上述情况中创建多列索引的方法更好。

5. 我们可以在列的表达式上创建索引,例如(lower(col1));((first_name || ' ' || last_name))等。索引表达式的维护相对较昂贵,因为每次插入或更新行时都必须计算派生表达式。在检索速度比插入和更新速度更重要时,索引表达式很有用。

6. PostgreSQL支持仅使用索引进行扫描,即仅通过索引回答查询而无需随机访问堆,前提是它主要是B-tree索引,并且查询只能引用存储在索引中的列。只有当表的堆页中的显式位图被设置为全部可见时,这才会产生优势。但是,表中有大部分行不变的情况很常见,因此在实践中,这种扫描类型非常有用。

7. 要有效利用仅索引扫描功能,可以选择创建覆盖索引,这是一种专门设计用于包含常用查询所需列的索引。由于查询通常需要检索的列不仅仅是搜索列,PostgreSQL允许您创建一个索引,其中一些列仅是“有效负载”,并且不是搜索键的一部分。可以通过添加包含额外列的INCLUDE子句来实现。

8. 对于添加非键有效负载列到索引中,特别是宽列,要保持保守。如果索引元组超过索引类型允许的最大大小,数据插入将失败。无论如何,非键列会复制索引表中的数据,并使索引的大小增大,从而可能减慢搜索速度。请记住,除非表的更改速度足够慢,以至于索引仅扫描不需要访问堆,否则在索引中包含有效负载列几乎没有意义。如果必须访问堆元组,从那里获取列的值不会增加额外成本。

9. 后缀截断从上层B-Tree级别中删除非键列。作为有效负载列,它们永远不会用于引导索引扫描。当剩余的键列前缀恰好足以描述最低B-Tree级别上的元组时,截断过程还会删除一个或多个尾随键列。在实践中,没有INCLUDE子句的覆盖索引通常会避免存储在上层的有效负载列。然而,明确定义有效负载列作为非键列可靠地保持上层元组的大小。

10. 原则上,表达式索引可以与仅索引扫描一起使用。然而,PostgreSQL的查询规划器在这种情况下目前并不聪明。它只有在查询所需的所有列都可以从索引中获取时,才认为可以通过仅索引扫描来执行查询。例如,对于在f(x)上进行搜索的查询,除了在f(x)的上下文中需要x外,x并不需要,但规划器没有注意到这一点,并得出结论无法进行仅索引扫描。如果仅索引扫描似乎非常值得,可以通过将x作为包含的列添加来解决此问题。部分索引也支持仅索引扫描。

11. 每个索引列只能支持一个排序规则。如果需要多个排序规则,则可能需要多个索引。索引会自动使用底层列的排序规则。

12. 在检查索引使用情况之前,务必先运行ANALYZE命令。该命令收集关于表中值分布的统计信息。这些信息用于估计查询返回的行数,规划器需要根据每个可能的查询计划分配实际的成本。如果没有实际的统计信息,将假定一些默认值,几乎肯定是不准确的。

13. 使用非常小的测试数据集来检查索引使用是致命的。从10万行中选择1000行可能适合使用索引,但选择100行几乎不适合,因为100行可能适应单个磁盘页,而没有任何计划可以超越顺序获取1个磁盘页。

针对上述每个要点评估设计的每个索引,并进行明智的索引设计过程。

另外,我需要指出,在从SQL Server迁移到PostgreSQL时,请不要直接将SQL Server的索引迁移到PostgreSQL。两种软件的索引架构非常不同。因此,在迁移到PostgreSQL时需要重新评估和重新设计索引。这将需要一些工作,但它会值得。


作者:Yasub Jiruwala

更多技术干货请关注公号“云原生数据库

squids.cn,基于公有云基础资源,提供云上 RDS,云备份,云迁移,SQL 窗口门户企业功能,

帮助企业快速构建云上数据库融合生态。


http://www.ppmy.cn/news/101750.html

相关文章

基于改进ISODATA算法的负荷场景曲线聚类(matlab代码)

目录 1 主要内容 聚类中心选取步骤 核方法 2 部分代码 3 程序结果 4 程序链接 1 主要内容 程序复现文献《基于机器学习的短期电力负荷预测和负荷曲线聚类研究》第三章《基于改进ISODATA算法的负荷场景曲线聚类》模型,该方法不止适用于负荷聚类,同样…

基于分布式ADMM算法的考虑碳排放交易的电力系统优化调度研究(matlab代码)

目录 1 主要内容 目标函数 计算步骤 节点系统 2 部分代码 3 程序结果 4 下载链接 点击直达! 1 主要内容 程序完全复现文献《A Distributed Dual Consensus ADMM Based on Partition for DC-DOPF with Carbon Emission Trading》,建立了一个考虑…

IDEA-报错 Failed to read artifact descriptor for xxx解决方法

项目场景: idea下载若依微服务的项目,配置环境产生了报错 问题描述 在idea里配置环境时maven报错Failed to read artifact descriptor for xxxx 原因分析: 在进行导包的时候maven和jdk版本导致的,更换版本之后大部分报错不存在…

解析云盘存储的优缺点:安全靠谱还是存在风险?

云盘是一种基于云计算技术的在线存储服务,用户可以通过互联网将文件上传到云端,并可以随时随地通过网络访问这些文件。 相较于传统的本地存储,云盘具有以下优势: 1.数据安全性更高:云盘使用专业的云计算技术和安全措施…

HTMLCSS中的树形结构图

我们可以只使用 html 和 css 创建树视图(可折叠列表) &#xff0c;而不需要 JavaScript。可访问性软件将看到树形视图作为列表嵌套在披露窗口小部件中&#xff0c;并且自动支持标准键盘交互。 1、HTML 我们就从简单嵌套列表的 html 开始: <ul><li>Giant planets&…

水文水资源模型合集

详情点击链接&#xff1a;EFDC建模方法及在地表水环境评价、水源地划分、排污口论证详情点击链接&#xff1a;基于SWMM及自主开发城市内涝一维二维耦合软件的复杂城市排水系统建模技术及在城市排涝、海绵城市 详情点击链接&#xff1a;HSPF(Hydrological Simulation Program F…

一步一步的指导构建基于ESP32的WEB服务器控制LED代码实现

在这篇博文中,我们将探讨如何从头开始构建 ESP32 LED 网络服务器。我们将完成设置ESP32、连接 LED以及创建 Web 界面来控制它们的步骤。 让我们简要了解一下我们需要做什么才能使我们的网络服务器正常工作 连接 ESP32 上的 GPIO12 和 GPIO14 上的 LED,以便您可以控制它们编码…

【Java SE】值传递,看这一篇就够了!

目录 一. 🦁 实参?形参?二. 🦁 值传递和引用传递三. 🦁 值传递到底传递啥?1. 传递基本参数类型2. 自定义对象类型参数传递3. 数组对象参数传递四. 🦁 小结一. 🦁 实参?形参? 程序设计语言在使用方法时(有些叫函数),都有可能会涉及到传递参数,而参数在其中分…