部分索引只收录一部分行,因此“查询用了同一张表、同一个列名”还不足以证明它适用。对于数据库软件的技术交接,关键问题是:查询要找的行,是否一定处在索引已经收录的范围内。这个范围关系解释不清,索引存在本身就容易被误当成查询已经获得优化。
PostgreSQL 17第11.8节将部分索引定义为建在表中一个子集上的索引,子集由条件表达式,也就是索引谓词决定,只有满足该谓词的行才有索引条目。[1] 索引键列与谓词涉及的列不一定相同:前者说明按什么内容建立索引,后者限制哪些行进入索引,二者回答的问题不同。
文档的未结算订单例子很直观。索引仅包含billed is not true的行,查询如果也具有这一条件,再加订单号限制,才具备文中所示的范围依据。单独按订单号寻找一条订单,则无法仅凭订单号知道它是否已结算。那条记录可能处在索引外,所以不能用这份部分索引代替完整查找范围。
原文进一步要求,系统能够识别查询WHERE条件在数学上蕴含索引谓词。这里还有“能够识别”的限定:规划器没有通用的复杂定理证明器,只能认出部分简单关系,例如x小于1可以推出x小于2;其他情形通常要求谓词与查询条件的一部分准确匹配。人认为两种写法等价,并不自动证明规划器也已识别。
核对发生在查询规划阶段,不能等到运行时再补上证明。文档用带参数的x小于问号说明:对于所有可能参数值,该条件并不都能推出x小于2。这个例子讲的是所示参数条件无法提供所需的普遍范围保证,不能改写成任何带参数的查询都永远不能使用任何部分索引。
上述判断首先解决索引是否可用,不负责证明项目中一定更快。原文提醒,部分索引需要对数据分布与查询负载有足够了解;排除一部分值也会使这些值无法通过该索引访问。整理评估报告时,可以把谓词、查询条件与规划器能识别的关系写在一起,再将实际性能证据单独记录。本文未连接数据库、创建索引或执行查询,不能给出读者生产负载的速度结论。
信息来源
本文基于上述公开资料整理,未使用来源页面的图片、视频或嵌入媒体。