想象一个表,其中的列a和b.
查询运行有点像这样:
SELECT col1, col2 FROM <table> WHERE a = 'value_1 AND b = 'value_2';
Run Code Online (Sandbox Code Playgroud)
现在,这个查询是否总是使用两列上的索引?如果是,机制是什么?如果没有,当有多个索引可用时,MySQL 是否会检查以决定使用哪个索引?
我发现当一个表同时具有聚集索引和非聚集索引(在不同的列上)时,叶级非聚集页,而不是指向数据行,指向聚集索引的节点,从那里另一个搜索用于查找数据行。这个额外的间接级别有什么意义?如果聚集索引有 8 个级别,那么从 NCI 叶页到 CI 根的间接访问将必须遍历这 8 个级别才能到达数据。为什么不把普通的RID存储在NCI的叶子页面中,这样我们就可以不用经过CI的索引结构就可以一次访问数据呢?
我正在simple-talk上阅读有关索引的文章,其中写道
如果堆上有一个非聚集索引(作为主键),并且数据被插入到表中,则必须发生两次写入。一次写入用于插入行,一次写入用于更新非聚集索引。另一方面,如果一个表有一个聚集索引作为主键,插入只需要一次写入,而不是两次写入。这是因为聚集索引及其数据是一体的。因此,将行插入到以聚集索引为主键的表中比将相同的数据插入到以非聚集索引为主键的堆中要快。无论主键是否单调递增,都是如此。
是不是错了?聚集索引自然求助于 B+ 树,其中只有键存储在中间节点中(与 B 树不同,B 树存储整个记录。这就是为什么 B+ 树可以在单个页面中容纳更多键,导致其宽度庞大但高度较短),因此所有记录都存储在叶子页面中(页面本身通过链表进行逻辑排序,而每个页面中的数据进行物理排序)。因此,如果必须更新记录,例如必须将值 1 更新为 7,则更新是否需要同时应用于聚集索引顶部节点中的两个键(在某些情况下,这可能会导致重新整个结构的结构)和叶页中记录中的相应值?
更新:好的,我做了一些研究,发现除了初始树结构(其中一些值必须出现两次,例如节点中的键值),当插入新值时,它们正好适合叶页,而树被重组以适应这一点。但是,当插入 5 个值时,第 3 个值可能会导致第一个插入的值(当前仅占用叶级空间)级联,从而导致它被写入两次(一次在叶级,其他在叶级)指数水平)。当然,这种重写(虽然它们不会在插入时发生,但它们可以稍后发生)与每次插入到带有 NCI 的堆中时发生的两次写入相比要少得多,但是说没有重写也不是错吗?