Gur*_*ngh 5 sql postgresql performance
假设我有一个带有int列的表,而我将要读取的是MAX()int值.
如果我在该列上创建索引,Postgres可以执行该索引的反向扫描以获取该MAX()值.但是由于索引中除了一行之外的所有行都只是一个开销,我们可以获得相同的性能而无需创建完整的索引.
是的,可以创建一个触发器来更新跟踪MAX值的单行表,并查询该表而不是MAX()针对主表发出一个表.但我正在寻找一些优雅的东西,因为我知道Postgres有部分索引,而我似乎无法找到一种方法来为此目的利用它们.
更新:这个部分索引定义理想情况下是我想要的,但Postgres不允许部分索引的WHERE子句中的子查询.
create index on test(a) where a = (select max(a) from test);
您不能在部分索引的谓词中使用聚合函数或子查询表达式.鉴于IMMUTABLE索引条目的性质,无论如何,这在逻辑上几乎没有任何意义.
如果你有一系列整数,并且你可以保证最大值总是大于x,那么你可以从这个元信息中受益.
CREATE INDEX text_max_idx ON test (a) WHERE a > x;
Run Code Online (Sandbox Code Playgroud)
如果包含WHERE与索引谓词匹配的子句,则此索引仅供查询计划程序使用.例如:
SELECT max(a) FROM test WHERE a > x;
Run Code Online (Sandbox Code Playgroud)
可能有更多条件,但必须包含此条件才能使用索引.
不过,我对"保证"很认真.如果谓词为false,则查询将不返回任何内容.
您可以构建一个故障安全:
SELECT COALESCE( (SELECT max(a) FROM test WHERE a > x)
(SELECT max(a) FROM test));
Run Code Online (Sandbox Code Playgroud)
您可以使用多个部分索引来概括此方法.类似这种技术,只是很多简单.
不过,我会考虑触发器方法,除了表上非常大的写入负载.
索引中的其他行不是必需的,因为它们使您即使在删除的情况下也能保持最大准确度,或者在更新的情况下减少当前最大值.
如果您没有这样的操作(IOW最大值只会增加),您可以自己保持最大值.在应用程序代码或触发器中执行此操作.
Postgres无法知道max只会增加.它必须坚持删除和更新的能力.