两列的唯一索引加上每一列的单独索引?

Posted

技术标签:

【中文标题】两列的唯一索引加上每一列的单独索引?【英文标题】:Unique index on two columns plus separate index on each one? 【发布时间】:2009-01-31 21:02:55 【问题描述】:

我对数据库优化不太了解,但我正在努力理解这个案例。

假设我有下表:

cities
===========
state_id integer
name varchar(32)
slug varchar(32)

现在,假设我想执行这样的查询:

SELECT * FROM cities WHERE state_id = 123 AND slug = 'some_city'
SELECT * FROM cities WHERE state_id = 123

如果我希望一个城市的“slug”在其特定州内是唯一的,我会在 state_id 和 slug 上添加一个唯一索引。

这个索引够吗?或者我还应该在 state_id 上添加另一个以便优化第二个查询?还是第二个查询自动使用唯一索引?

我正在研究 PostgreSQL,但我觉得这个案例非常简单,以至于大多数 DBMS 的工作方式都差不多。

另外,我知道这肯定不会对小桌子产生影响,但我的示例很简单。想想 200k+ 行的表。

谢谢!

【问题讨论】:

看来这个主题比我最初想象的要复杂。谢谢大家的意见。 【参考方案1】:

(state_id, slug) 上的单个唯一索引就足够了。可以肯定的是,当然,您需要运行 EXPLAIN 和/或 ANALYZE(可能在 http://explain.depesz.com/ 之类的帮助下),但最终哪些索引是合适的,很大程度上取决于您将运行的查询类型。请记住,索引使 SELECT 更快,而 INSERT、UPDATE 和 DELETE 更慢,因此理想情况下,您只需要实际需要的索引。

此外,PostgreSQL 有一个智能查询优化器:它将使用完全不同的搜索计划来处理小表和大表的查询。如果表很小,它只会进行顺序扫描,甚至不会打扰 any 索引,因为使用它们的开销比通过表的暴力筛选要高。一旦表大小超过阈值,这将更改为不同的计划,并且如果表再次变大,或者如果您更改 SELECT,或者......

总结:您不能相信 EXPLAIN 和 ANALYZE 对比您的实际数据小得多或不同的数据集的结果。让它发挥作用,然后再让它变得更快(如果你需要的话)。

【讨论】:

【参考方案2】:

[编辑:误读了问题...希望我的回答现在更相关!]

在您的情况下,我建议在 (state_id, slug) 上设置 1 个索引。如果您只需要通过 slug 进行搜索,请仅在该列上添加索引。如果你有这些,那么在state_id 上添加另一个索引是不必要的,因为第一个索引已经涵盖了它。

只要在 WHERE 子句中使用 其列的初始段,就可以使用索引。所以例如列 A、B 和 C 上的索引将优化包含涉及 A、B 和 C 的 WHERE 子句、仅包含 A 和 B 的 WHERE 子句或仅包含 A 的 WHERE 子句的查询。请注意,列在索引定义中出现的顺序非常重要——这个示例索引不能用于只涉及 B 和/或 C 的 WHERE 子句。

(当然,是否实际使用特定索引取决于查询优化器,但在您有 200k 行的情况下,您可以保证通过 state_idslug 或两者进行简单搜索将使用一个指数。)

【讨论】:

【参考方案3】:

任何体面的优化器都会在三列上看到一个索引 - 比如说:

CREATE INDEX idx_1 ON SomeTable(Col1, Col2, Col3);

并将在以下任何情况下使用该索引:

WHERE Col1 = ...something...

WHERE Col1 = ...something... AND Col2 = ...otherthing...

WHERE Col3 = ....whatnot....
  AND Col1 = ...something....
  AND Col2 = ...otherthing...

也就是说,如果有条件应用于索引列的任何连续前导子集,它将使用索引。虽然我使用了相等,但它也可以应用于范围(例如,开 - 刚好大于)或闭(在两个值之间)。

【讨论】:

【参考方案4】:

要进行优化,请使用 EXPLAIN http://www.postgresql.org/docs/7.4/static/sql-explain.html 并亲自查看。 但优化并不是制作这些索引的最重要原因;首先,它是一个限制数据库不合逻辑的约束。

【讨论】:

以上是关于两列的唯一索引加上每一列的单独索引?的主要内容,如果未能解决你的问题,请参考以下文章

唯一列的最佳索引类型,如果对数据进行物理排序,查询将更快

使用同一 Dataframe 中另一列的 int 作为索引获取列中的列表值

使用pandas创建稀疏矩阵,并使用来自.dat文件的其他两列的索引[x,y]的.dat文件的一列中的值填充它

主键,唯一索引 聚集索引的关系

IsUnique=Yes 的唯一键和索引有啥区别?

mysql的唯一索引UNIQUE