bra*_*orm 3 mysql sql indexing clustered-index non-clustered-index
我最近一直在阅读如何clustered index
和non-clustered index
有效的方法.我用简单的术语理解(如果错误,请纠正我):
支持clustered
和non-clustered index
存在的数据结构B-Tree
Clustered Index
:根据索引列(或键)对数据进行物理排序.你只能有一个clustered Index
每个table
.如果没有index
表创建过程中指定,SQL
服务器将自动创建clustered Index
的primary key column
.
Q1:由于数据是根据索引进行物理排序的,因此这里不需要额外的空间.它是否正确?那么当我删除我创建的索引时会发生什么?
Non-clustered Index
:在non-clustered indexes
,leaf-node
树的包含列值和指向数据库中实际行的指针(行定位器).这里存在将non-clustered index table
物理存储在磁盘上所需的额外空间.但是,一个不受数量的限制non-clustered Indexes.
Q2:这是否意味着对非聚集索引列的查询不会导致排序数据?
问题3:此处有一个额外的查找,用于使用叶节点处的指针定位实际的行数据.与聚簇索引相比,这会有多大的性能差异?
锻炼; Tibial:
考虑一个Employee表:
CREATE TABLE Employee
(
PersonID int PRIMARY KEY,
Name varchar(255),
age int,
salary int
);
Run Code Online (Sandbox Code Playgroud)
现在我创建了一个employee表(创建了employee上的默认聚簇索引).
此表上的两个常见查询仅发生在年龄和工资列上.为简单起见,我们假设表不经常更新
例如:
select * from employee where age > XXX;
select * from employee where salary > XXXX and salary < YYYY;
Run Code Online (Sandbox Code Playgroud)
问题4:构建索引的最佳方法是什么,以便这两列上的查询具有相似的性能.如果我在年龄列上的年龄查询上有聚簇索引会更快但是在工资列上会更慢.
问题5:在相关的说明中,我反复看到应该在具有唯一约束的列上创建索引(聚簇和非聚簇).这是为什么?未能做到这一点会发生什么?
非常感谢我阅读的帖子在这里:
我不知道Microsoft SQL Server的内部,但我可以回答MySQL,你标记了你的问题.其他实现的细节可能有所不同.
Q1.没错,聚集索引不需要额外的空间.
如果删除聚集索引会发生什么?MySQL的InnoDB引擎始终使用主键(或第一个非空唯一键)作为聚簇索引.如果您定义没有主键的表,或者删除现有表的主键,InnoDB会为聚簇索引生成内部人工密钥.此内部键没有逻辑列来引用它.
Q2.不保证由使用非聚集索引的查询返回的行顺序.实际上,它是访问行的顺序.如果需要按特定顺序返回行,则应ORDER BY
在查询中使用.如果优化器可以推断出您所需的顺序与它将访问行的顺序(索引顺序,无论是通过聚簇索引还是非聚集索引)相同,那么它可以跳过排序步骤.
Q3.InnoDB非聚集索引没有指向索引叶子上相应行的指针,它具有主键的值.因此,非聚集索引中的查找实际上是两个B树搜索,第一个是查找非聚集索引的叶子,然后是聚簇索引中的第二个搜索.
这是单个B树搜索(或多或少)的两倍,因此InnoDB有一个额外的功能,称为自适应哈希索引.经常搜索的值会缓存在AHI中,并且下次查询搜索缓存值时,它可以执行O(1)查找.在AHI缓存中,它找到一个直接指向聚簇索引的叶子的指针,因此它在一部分时间内消除了 B树搜索.
提高总体性能的程度取决于您搜索之前搜索过的相同值的频率.根据我的经验,哈希搜索与非哈希搜索的比率通常约为1:2.
Q4.构造索引以提供需要优化的查询.通常,聚簇索引是主键或唯一键,至少在InnoDB的情况下,这是必需的.既不age
是salary
也不可能是独一无二的.
您可能会喜欢我的演示文稿,如何设计索引,真的.
Q5.声明唯一约束时,InnoDB会自动创建索引.如果没有为其存在索引,则不能拥有约束.如果您没有索引,那么在插入值时引擎如何确保唯一性?它需要在整个表中搜索该列中的重复值.该索引有助于使独特的检查更加有效.
归档时间: |
|
查看次数: |
4531 次 |
最近记录: |