【问题标题】:Combined Multiple Column Index as well as Multiple Single Column Indices组合多列索引以及多个单列索引
【发布时间】:2014-01-25 11:46:24
【问题描述】:

我想知道在以下情况下同时定义这两种类型的索引有什么害处。

Tasks:

  TaskID (Primary, Auto Number)
  OwnerID (Single Column Index)
  AssignedToID (Single Column Index)
  DateUpdated (Single Column Index)
  TaskStatus (Single Column Index)

  Mutli Column Index (AssignedToID, DateUpdated)

有以下主要查询...对DateUpdated 的查询是可选的。

  • 管理员可以按日期过滤任务
  • 单列索引 DateUpdated 被访问

    WHERE 
        DateUpdated <= startDate 
        AND DateUpdated <= endDate
    ORDER BY
        DateUpdated DESC
    
  • 单列索引 DateUpdated 被访问

    WHERE
         TaskStatus = 'Active' 
    ORDER BY
         DateUpdated DESC
    
  • 用户可以过滤仅分配给他们的任务

  • 多列索引被访问

    WHERE 
        DateUpdated <= startDate 
        AND DateUpdated <= endDate
        AND AssignedToID = userID
    ORDER BY
        DateUpdated DESC
    
  • 多列索引被访问

    WHERE 
         AssignedToID = userID
         AND TaskStatus = 'Active'
    ORDER BY
         DateUpdated DESC
    
  • DateUpdated 未在任何条件中引用

  • 单列索引TaskID被访问

    WHERE 
        AssignedToID = userID
        AND TaskStatus = 'Active'
    ORDER BY
        TaskID DESC
    

看起来我可以通过在某些频繁查询中定义多列索引来提高性能,我有以下问题。

  1. 同时定义组合索引和多个索引有什么坏处吗?
  2. 如果查询包含每个列的谓词,而不管查询中列的顺序如何,SQL 是否会优先考虑组合索引而不是单个索引合并?
  3. 如果您有任何两个索引都可能有害的示例,我想了解原因和方法,以便我可以相应地设计我的索引。

我的数据库操作是 95% 读取和 5% 写入,所以我不太担心索引写入性能问题,但我的读取性能是最重要的。

【问题讨论】:

    标签: sql-server indexing


    【解决方案1】:

    同时定义组合索引和多个索引有什么坏处吗?

    我宁愿称其为维护开销而不是伤害:
    - 对于每个新索引,此表上的 INSERT/UPDATE/DELETE 会稍微慢一些。
    - 索引占用一些磁盘空间。

    如果查询包含每个列的谓词,而不管查询中列的顺序如何,SQL 是否会优先考虑组合索引而不是单个索引合并?

    查询中列的顺序无关紧要。

    索引中列的顺序很重要。
    所以:
    (AssignedToID, DateUpdated) 上的索引可用于查找而不是 (AssignedToID) 上的索引,但是
    (DateUpdated, AssignedToID) 上的索引不能用于查找而不是 (AssignedToID) 上的索引。

    查询优化器将根据估计的成本选择要使用的索引,并根据统计信息(表/索引中有多少行,以及值的分布方式)进行计算。
    它可能决定根本不使用您的索引 - 如果行数很少并且扫描整个表更便宜,或者如果索引没有足够的选择性。

    如果查询包含AssignedToIDDateUpdated 上的谓词,则查询优化器更有可能使用(AssignedToIDDateUpdated)上的索引而不是(AssignedToID)上的索引。
    但是,这取决于查询的所有其他元素以及数据库中的实际数据。

    如果您有任何两个索引都可能有害的示例,我想了解原因和方法,以便我可以相应地设计我的索引。

    当数据库或/和请求数量显着增长时,开销可能会变得很明显。

    More about "too many indexes"
    General indexing guidelines


    根据您的主要查询,看起来非聚集索引应该是:

    • (DateUpdated)
    • (AssignedToID, DateUpdated)

    也许:

    • (TaskStatus) - 但是如果假设 90% 的任务是 'Active' 而你只查询 'Active' - 那么它就没有用了。

    不需要:

    • (AssignedToID) - 因为 (AssignedToID, DateUpdated) 索引就足够了。

    之后,您可以在测试数据库上验证假设,数据与生产环境足够接近。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-27
      • 2013-11-05
      • 2021-09-01
      • 2020-05-06
      • 1970-01-01
      • 2019-03-22
      • 2011-11-07
      • 2010-09-15
      相关资源
      最近更新 更多