假设您想优化 postgres 数据库中的查询,例如:
SELECT DISTINCT ON (first)
first,
second,
third
FROM my_table
WHERE
second > 100
AND fourth = 3
ORDER BY
first,
second DESC,
third DESC
(编辑:在此示例中,假设
fourth=3
约为行的 25%,而 second > 100
仅约为 5%)
您想要根据几个过滤条件并按其他三个条件排序来选择表格的第一列。据我所知,最好的方法是在
first and second
上创建索引,然后在 first, second DESC, third DESC
上创建索引。不幸的是,当我分析查询时,第二个索引似乎没有被使用。
这是创建这些索引的理想方式吗?或者是否可以有一个索引来统一过滤和排序。
其次,我想知道,有没有一种方法可以确保您选择给定表的最佳索引策略,或者是否可以根据您的数据集和查询来分析确定?
当我现在运行它时,这是我当前的解释输出:
Unique (cost=207985.91..208536.43 rows=18682 width=78) (actual time=823.330..965.769 rows=5248 loops=1)
-> Sort (cost=207985.91..208261.17 rows=110104 width=78) (actual time=823.328..935.933 rows=348232 loops=1)
Sort Key: first, second DESC, third DESC
Sort Method: external merge Disk: 31176kB
-> Index Scan using ix_my_table_second_fourth on my_table (cost=0.44..193872.52 rows=110104 width=78) (actual time=0.017..103.031 rows=348232 loops=1)
Index Cond: ((fourth = 3) AND (second > 100))
Planning Time: 0.315 ms
Execution Time: 971.174 ms
因此您可以看到它使用
ix_my_table_second_fourth
进行过滤,但大部分时间都花在对查询进行排序上,以便获得每个 second
列具有最高 third
和 first
值的值。
虽然
DISTINCT ON
是最好的查询技术(并且模拟索引跳过扫描是没有代价的),但优化行选择索引而不是预排序应该是最有效的
CREATE INDEX ON tbl (fourth, second DESC NULLS LAST) INCLUDE (first)
second > 100
比 fourth = 3
更具选择性,但这对于索引列的顺序几乎不重要,只要两者都处于领先位置即可。决定因素:相等位于范围谓词之前。 first
列对过滤没有帮助,因此不妨移至 INCLUDE
部分以使索引小一点。
基于不完整信息的初步建议。