【问题标题】:Indexes and Nested Sets索引和嵌套集
【发布时间】:2011-07-05 14:09:11
【问题描述】:

我正在使用嵌套集来表示我的应用程序中的层次结构,并且想知道放置索引(集群或其他)的最佳位置在哪里。我正在使用 Microsoft SQL Server 2008。

操作:

  1. 每天大约 40 次,将在根目录下添加一个新层次结构。
  2. 层次结构可能永远不会被删除。
  3. parentId 在白天经常访问层次结构,以逐步填充组合框。
  4. 很少移动层次结构。可能甚至一个月都不会。
  5. 与其他表链接时,最大的访问是通过左右。这是迄今为止对层次结构最频繁的访问。

我曾尝试在左侧和右侧放置一个聚集索引(大多数情况下,它会使用 val BETWEEN @left AND @right 进行查询。但是在左侧和右侧进行聚集是正确的方法吗?

非常感谢在 SQL 索引方面比我更有经验的人!

目前的架构

_id       INT IDENTITY NOT NULL
_idParent INT IDENTITY NULL
_name     NVARCHAR(64)
_left     INT NOT NULL
_right    INT NOT NULL

【问题讨论】:

  • 你能提供一个关于模式的想法吗?

标签: sql sql-server indexing nested-sets


【解决方案1】:

最好的办法是测试各种索引配置,然后看看哪种效果最好。乍一看,聚集在 lft 和 rgt 上似乎是最好的。听起来表上没有太多 DML,所以它不应该经常重新排列数据,并且 lft 和 rgt 上的聚集索引应该将您的大部分查询变成聚集索引扫描/搜索。

我看到的唯一缺点是,如果您将层次结构放在根的正下方,那么它可能还涉及移动许多其他层次结构。你会一直添加到根的“右侧”吗?这只涉及更新根行中的 rgt 列,这很好。如果添加到根左侧的中间,则必须将所有其他层次结构移到新层次结构的右侧。另外,你的桌子有多大?这会对事情产生一些影响。如果它足够小,那么转移这些层次结构可能无论如何都不是什么大问题。如果可以的话,你肯定想尝试插入到根的右侧。

编辑:另外一件事...您是否查看过 SQL Server 内置的 hierarchyid 数据类型?

【讨论】:

  • 您好,感谢您的及时回复。一般是的,只加在右边。基本上,在根目录下会有一个公司列表。这目前在 130 左右,但这很容易达到数千。每个下面通常是 1 个,但多达 8 个子节点。然而,它永远不会比这更深入。
  • 在这种情况下,您可能对您建议的索引处于良好状态。顺便说一句,如果 _idParent 仅指向分层父级,则您不需要它。这是数据的重复和的想法。此外,如果您将基于_id 加入此表,那么请考虑在其他列上使用INCLUDES 的非聚集索引(假设您上面的架构显示所有列)。当然,再次测试各种设置。
  • 我使用 parentId 因为有时我必须在给定任意级别的任意项目的情况下“向上”行走。此外,我使用它来仅获取给定节点的直接后代(用于增量填充用户界面元素)。当然,如果有更好的方法可以做到这一点,我会很感激你的帮助,尽管它可能属于“另一个问题”的类别?
  • 我会建议谷歌搜索“Joe Celko 嵌套集模型”,但很难找到具体的查询。如果你能找到他关于这个主题的书的副本,那是一本很好的读物。我没有我的副本。查找直接子级和父级涉及获取父级COUNT(*) 的子查询,以便您可以确定项目在层次结构中的级别。或者,您可以在表中包含该列以使查询更容易,尽管我刚刚谴责另一张海报在数据库中包含重复数据:)
  • 有时我们必须做我们必须做的事情来让生活变得更简单一点。奇怪的是你建议谷歌搜索,因为这是我在给你写评论之前所做的,我似乎找不到我基于我的代码的原始文章。甲骨文还撤下了大多数人曾经链接到的 mysql 站点上的那个站点。甲骨文干得好!非常感谢您的帮助和及时回复。
【解决方案2】:

我会担心以这种方式使用聚集索引——它的查询速度非常快,但任何插入/更新/删除都可能需要在磁盘上重新写入数据;这可能会造成严重的性能问题(尤其是对于大型表)。

我还建议,在实践中,您不太可能注意到聚集索引和非聚集索引之间的区别——尤其是索引整数。如果你有巨大的表——数亿条记录——你可能能够测量出差异,但在现代硬件上,我认为它不会产生明显的差异。

所以,我同意 Tom H. - 试试看,然后衡量。确保您测量插入/更新/删除以及查询。除非您注意到真正显着的性能优势,否则我倾向于使用聚集索引作为主键 - 因为根据定义,这是不可变的。

【讨论】:

    猜你喜欢
    • 2011-05-24
    • 1970-01-01
    • 2012-03-18
    • 2023-03-20
    • 2012-02-01
    • 2011-09-14
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    相关资源
    最近更新 更多