postgresql SQL相关列筛选和排序

cwtwac6a  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(132)

我有一个表,其中有许多不同类型的列,我用它来过滤和排序结果(这类似于带排序的分面搜索)。
让我们考虑2列:AB。为每一列创建一个索引。
我们要查询A=value ORDER BY B LIMIT 10
如果计划程序将使用A索引,则它必须扫描具有A=value的所有行,并按B对它们进行排序。
如果计划程序将使用B索引,则它将扫描所有行,直到找到10个具有A=value的行。
我们一共有2500000行,50000行有A=value,所以每50行有一个A=value,所以它认为只要扫描50*10=500行就可以找到10个A=value行,但是它错了,因为两个字段之间有相关性,A=value行分布不均匀,但它们位于B索引的末尾,因此实际上需要扫描超过2000000行。
如果我们禁用B索引,那么它是好的。但是,我们希望B索引用于其他查询。
如何解决问题?
创建(A,B ASC)索引不是一个好的解决方案。因为索引太多,而且A可能是数组类型,不支持这样的索引。

pgx2nnw8

pgx2nnw81#

对于这个问题没有很好的通用解决方案。你可以通过在SQL中添加一些伪操作来强制它不使用B上的索引来进行逐案排序,比如:

ORDER BY B+0 LIMIT 10

ORDER BY B||'' LIMIT 10

PostgreSQL的未来版本总是有可能“看穿”这些伪操作并使用该索引。
如果B上的索引只需要支持相等比较,那么你可以把它变成一个HASH索引或GIN索引(通过btree_gin扩展),这不能用于排序,但仍然可以用于相等比较。

相关问题