是否为此连接用法正确定义了此索引? (Postgres的)

时间:2018-03-27 16:33:00

标签: sql postgresql indexing

select
    *
from
    tbl1 as a
inner join
    tbl2 as b on
    tbl1.id=b.id
left join
    tbl3 as c on 
    tbl2.id=tb3.parent_id and
    tb3.some_col=2 and
    tb3.attribute_id=3

在上面的示例中:

如果我想在连接上获得最佳性能,我应该在 tbl3 上设置索引吗?

parent_id,
some_col,
attribute_id

2 个答案:

答案 0 :(得分:1)

答案取决于所选的连接类型。

  • 如果PostgreSQL选择嵌套循环或合并外连接,则索引是完美的。

  • 如果PostgreSQL选择散列外连接,索引根本不会有帮助。在这种情况下,您需要(some_col, attribute_id)上的索引。

EXPLAIN合作,为您的案件做出最佳选择。

注意:如果some_colattribute_id上的某个条件没有选择性(不会过滤掉大量的行),通常会最好在索引中省略该列。在这种情况下,最好是获得较小索引和更多HOT更新的好处。

答案 1 :(得分:0)

我的回答是“可能”。我是根据SQL Server的经验发言的,所以有人请纠正我,如果我错了,它在Postgres中是不同的。

您的索引在大多数情况下看起来很好。可能出现的问题是使用SELECT *。如果tbl3的列数多于索引中定义的列数,并且您要查询这些字段,则它们将不在您的索引中,并且引擎将不得不在该索引之外执行其他查找。

另一件事是基于你的领域的基数,这意味着哪些是最有选择性的。如果parent_id具有高基数,意味着很少重复,则可能导致对索引的更多读取。但是,如果您的最低基数字段是第一个并且数据库可以快速过滤掉大量数据,那么这可能会更有效。

我看到两者在SQL Server中都运行良好。 SQL Server甚至推荐索引,我应用它们,然后根据字段基数推荐不同的索引。同样,我不熟悉Postgres引擎,我只是假设这些主题适用于两者。如果所有其他方法都失败了,请创建具有不同列顺序的3个索引,并查看引擎最喜欢哪个索引。