postgresql:具有外键的多个多列索引?
Posted
技术标签:
【中文标题】postgresql:具有外键的多个多列索引?【英文标题】:postgresql: multiple multicolumn indexes with foreign key? 【发布时间】:2015-05-21 05:52:40 【问题描述】:简单的问题。假设我有一个 users 表和一个 cars 表。汽车表有一个user_id、make、model,我总是用user_id查询它的数据:
SELECT * FROM cars WHERE user_id = 123 AND make = 'honda'
SELECT * FROM cars WHERE user_id = 123 AND model = 'accord'
假设我总是使用 user_id 查询汽车表,是添加两个多列索引 [user_id, make] 和 [user_id, model](可能更多用于附加列),还是为每个索引添加一个单列索引更好user_id、品牌和型号列?
让我感到困惑的是有几个多列索引都以相同的外键开头的想法。似乎这最适合我的查询,但不确定它对数据库有多正确/高效/浪费。
【问题讨论】:
不同之处在于,如果使用 AND 条件,多列索引将成为覆盖索引,因此优化器不必触摸表进行搜索,只需进行检索。所以可以使用第一个选项,不确定,但 Postgres 不能同时使用 2 个索引,因此对于 OR 条件,它可能会选择条件最严格的索引 @米海。这不是 覆盖查询 的意思。你混淆了这个问题。 【参考方案1】:此答案考虑了数据库中最“正确/高效/最不浪费”的内容。
假设我总是使用 user_id 查询汽车表,
您对数据的处理方式或访问方式与数据库设计和整体性能无关。它仅与单个查询相关。
是添加两个多列索引 [user_id, make] 和 [user_id, model](对于附加列可能更多),还是为每个 user_id、make 和模型列添加一个单列索引更好?
单列索引是多余的,是个无能者,它没有任何收获。
另外,您应该更新每一列的统计信息。首先,与您的问题分开,PK 应该是:
( user_id, make, model )
因为(没有看到表的完整 DDL),这是提供行唯一性的唯一方法,这在关系数据库中是必需的。即使添加了属性列,您也不需要额外的索引。
如果您在该文件中有一个 car_id 字段,由于它需要额外的索引,它是多余的、多余的和负面的性能。您可以安全地删除它。其次,对于您所描述的查询,该 PK 索引是您唯一需要的。
让我感到困惑的是,有几个多列索引都以相同的 foreign_key 开头。*
是的,这应该会引发警报。并不是说它们都以相同的 FK 开头,而是它们以相同的列开头。具有最大列集的索引使其他列变得多余。
【讨论】:
你为什么假设单个用户不能拥有两辆具有相同(make, model)
的汽车?
你可以假设有一个 PK id,为了简单起见,我把它省略了。因此,为 user_id、make 和 model 添加单列索引将导致我的查询仅使用 user_id 索引而不是其他索引,听起来像是。以同一列(user_id)开头的两个多列索引是多余的吗?那么解决方案是什么呢?如果要索引 [user_id, make, model],似乎两个查询都会使用该索引 - 但是,如果我有更多列,我必须以同样的方式查询,我会继续将它们添加到该索引吗?似乎该索引可能会变得很大。
@RadekPostołowicz。我没有假设任何事情。我使用了詹姆斯提供的信息。你的问题超出了詹姆斯的问题,超出了我的回答。如果用户可以拥有两辆相同品牌和型号的汽车,那么确实应该有一个附加列,例如。 SequenceNo
提供独特性。
@詹姆斯。是的,大部分都是这样。 在这种情况下,一个索引就足够了。但是,如果您“继续添加列”,需要对其进行索引,后者是一个单独的决定,那么您必须再次评估索引。我会添加一个单独的索引,具有不同的列组合,具有不同的起始列。不要随意添加索引,只是为了克服 NONsql 的愚蠢。以上是关于postgresql:具有外键的多个多列索引?的主要内容,如果未能解决你的问题,请参考以下文章