【问题标题】:What's the difference between making an index on 2 columns and an index on each of the columns separately?在 2 列上创建索引和在每列上分别创建索引有什么区别?
【发布时间】:2008-12-16 22:23:11
【问题描述】:

我是数据库索引的新手,如果我的表中有 2 列是索引的好选择,例如,

[Posts](    
   [PostID] [int] IDENTITY(1,1) NOT NULL,
   [UserName] [nvarchar](64) NOT NULL,
   [ApplicationType] [smallint] NOT NULL,
   ...
)

在这种情况下 PostID 将是 PRIMARY KEY CLUSTERED 索引,然后我想做更多的索引,因为它是一个大表,我想对 UserName 和 ApplicationType 做,现在我应该单独索引每个(一个在 UserName 上,一个在ApplicationType)或将它们作为一个整体索引(用户名、ApplicationType 上的一个索引一起)?在成为不好的做法之前,我可以拥有的索引数量是否有限制?这方面的经验法则一般是什么?

谢谢,

雷。

【问题讨论】:

    标签: database-design indexing


    【解决方案1】:

    请记住复合索引的电话簿规则:电话簿是按姓氏、名字有效索引的。这是一个复合索引。

    如果您搜索名为“Smith, John”的人,那么名字是索引的一部分会很有帮助。找到姓氏为“Smith”的条目后,您可以快速找到“John”。

    但如果您需要搜索名为“John”的每个人,那么电话簿的索引将无济于事——无论如何您都必须搜索整本书。

    因此,如果您要搜索索引中命名的第一列,也可以选择第二列等,那么复合索引非常有用。但如果您的搜索跳过了索引中最左边的列,则该搜索将毫无用处。

    【讨论】:

      【解决方案2】:

      这个问题的答案实际上取决于您将如何在桌子上进行搜索。如果您的搜索几乎总是包含这两列,那么在这两列上创建索引是合适的。如果您将经常单独搜索每个字段,那么为每个字段创建单独的索引是合适的。最后,您可以拥有所有 3 个索引(一个复合索引,2 个单列) - 取决于您如何使用这些列进行搜索。把它想象成电话簿——如果你总是用姓氏和名字搜索,你会找到你要找的东西。但是,如果您想在电话簿中搜索名字为 Scott 的每个人,您需要一个不是 (LName, FName) 的新索引。如果您想查找具有给定姓氏的每个人,您仍然可以使用 (LName, FName) 的多列索引来实现。

      每个数据库对每个表的索引数、每个索引的列数等都有自己的限制。它们通常足够高,如果您在这里查看 3 个索引,则不必担心它们.另外,请记住,您拥有的索引越多,维护它们的成本就越高(插入、更新、删除等)。

      【讨论】:

        【解决方案3】:

        IIRC,经验法则是索引只能用于使用从某个点到左侧的所有列的查找。例如,如果您查询 (a)、(a,b)、(a,b,c) 或 (a,b,c,d),则可以使用列 (a,b,c,d) 上的索引但不是在 (a,c) 上。

        这是索引构建方式的结果;最左边的列被索引,然后为该列的每个值创建下一列的索引,依此类推。


        编辑:正如 BQ 指出的那样,DBMS 可以扫描索引的完整“a”部分并查找“b”部分(我不知道这是实际完成的)。但是,这不如可以使用上述规则的索引快(OTOH,它可能比全表扫描更快)。

        就我个人而言,我认为不应有意利用这一点。如果性能足以引起您正在考虑需要哪些索引的给定查询的关注,那么您不妨给它正确的索引。

        【讨论】:

        • 这不适用于大多数 DBMS 的最新(和最近)版本。通常,如果您要在“c”列中查找某些内容,则扫描索引而不是整个表会更快。与往常一样,分析您的查询计划。
        猜你喜欢
        • 2014-08-25
        • 2018-09-01
        • 1970-01-01
        • 2011-07-01
        • 1970-01-01
        • 2019-02-27
        • 2013-11-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多