代码之家  ›  专栏  ›  技术社区  ›  John Leidegren

多租户聚集索引设计

  •  2
  • John Leidegren  · 技术社区  · 14 年前

    我有一个多租户应用程序,我希望数据的聚集索引支持快速范围查询。

    如果我像这样设计聚集索引:

    (SystemID, EntityID, IsHidden)
    

    SystemID 是多租户实例的唯一标识符, EntityID 是实体和 IsHidden 是否在结果中显示此行的标志。SQL Server是否能够有效地抛出不属于系统的所有数据以及隐藏数据?指定这些列的顺序是否重要?

    SELECT * FROM MyTable WHERE SystemID = @pSystemID AND IsHidden = 0
    

    我想我要做的是有效地对表进行分区,以便将属于特定系统的所有行以及隐藏的数据物理地分组在一起。这样,根据对该数据的查询,可以很容易地丢弃它。

    这是好是坏?(我倾向于好的,我不希望有很多插入发生)

    1 回复  |  直到 14 年前
        1
  •  3
  •   Remus Rusanu    14 年前

    改成这样: (SystemID, IsHidden, EntityID) . 拥有 IsHidden 之后 这个 EntityID 会让它变得毫无用处 已经是唯一的了。搜索作为示例提供的条件( WHERE SystemID=@SystemID AND IsHidden=0 IsHidden=0 分布在整个范围内。移动此列 之前 允许更有效的范围扫描。

    实体标识符 默认情况下效率低下( WHERE EntityID=@EntityID ). 您可以通过在 但这只能解决部分问题。大部分问题都将由与其他表的联接引起,如在以下条件下联接的详细信息表:

    FROM Master JOIN Detail ON Master.EntityID = Detail.ParentEntityID
    

    随着这些查询变得越来越复杂,候选行的范围也越来越大,在 实体标识符 / ParentEntityID the tipping point 基本上被忽略了。如果可能,确保 全部的 这些联接改为指定聚集索引键:

    FROM Master JOIN Detail 
       ON Master.SystemID = Detail.SystemID 
       AND Master.IsHidden = Detail.IsHidden 
       AND Master.EntityID = Detail.ParentEntityID
    

    问题是大多数建模工具(如EF或Linq)都倾向于通过逻辑主键(即 实体标识符 )与物理群集密钥相反。