谁能解释一下什么是索引碎片?我搜索了索引碎片,但找不到满意的答案。
1 回答
将所有不相关的技术方面放在一边;数据库上下文中的碎片是以无序方式存储的有序数据。这会导致不必要的性能开销,从而导致数据库速度变慢。
假设您与员工有一张桌子。该索引包含按员工身份编号访问员工的排序数据。索引包含按顺序存储的数据。为简单起见,我们有一个包含四名员工的表:
1 Anne
3 Charly
4 James
5 William
数据库引擎将一些员工存储在一个页面中。这通常是一个固定大小的排序桶。因此,让我们将员工放在一个页面中。假设我们只能在一个页面中放置两个员工。我们最终会得到:
[ Page 1, next page is page 2, there is no previous page ]
1 Anne
2 Charly
[ Page 2, there is no next page, but there is a previous page 1 ]
4 James
5 William
现在,当我们要添加标识号为 3 的 Bert 时,问题就出现了。它不适合任何一个页面。不是在第 1 页的末尾,也不是在第 2 页的开头。我们需要为 Bert 创建一个新页面,并修复(上一个和下一个)页面的引用,以便它们仍然是有序的。
[ Page 1, next page is page 3, there is no previous page ]
1 Anne
2 Charly
[ Page 2, there is no next page, but there is a previous page 3 ]
4 James
5 William
[ Page 3, next page is page 2, previous page 1 ]
3 Bert
请注意,第 3 页位于列表的末尾。数据库引擎仍然可以从第 1 页开始并以有序的方式浏览这些页面;即转到下一页 3,然后转到下一页 2。但这不是最佳选择。引擎需要来回跳转才能找到它的数据,而不是仅仅从第 1 页走到最后一页。这正是索引碎片的含义。
我们可以通过再次对页面进行排序(和重建)来对索引进行碎片整理。我将省略具体步骤,但这样做的结果是页面是有序的,并且它包含的数据也是有序的。
[ Page 1, next page is page 2, there is no previous page ]
1 Anne
2 Charly
[ Page 2, next page is page 3, previous page 1 ]
3 Bert
4 James
[ Page 3, there is no next page, previous page 2 ]
5 William
你可能会问,为什么不马上做呢?总会有取舍。更改最少的数据量(在这种情况下是页面)会打扰最少的其他用户(在这种情况下是其他查询或对数据库的更改)。在新页面放在最后的场景下,我们只需要更改几页。如果我们将索引更新为完全排序,则需要更改大部分页面,如果不是全部的话。在更改页面时,对同一页面(或更糟)的其他更改必须等待前一个更改被提交。