ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

mysql – 在SQL中优化基于聚簇索引和非聚簇索引的查询?

2019-07-25 05:14:38  阅读:324  来源: 互联网

标签:clustered-index non-clustered-index sql mysql indexing


我最近一直在读关于聚簇索引和非聚簇索引的工作原理.我用简单的术语理解(如果错误,请纠正我):

支持聚簇索引和非聚簇索引的数据结构是B-Tree

聚集索引:根据索引列(或键)对数据进行物理排序.每个表只能有一个聚簇索引.如果在创建表期间未指定索引,SQL Server将自动在主键列上创建聚簇索引.

Q1:由于数据是根据索引进行物理排序的,因此这里不需要额外的空间.它是否正确?那么当我删除我创建的索引时会发生什么?

非聚集索引:在非聚簇索引中,树的叶节点包含列值和指向数据库中实际行的指针(行定位器).这里存在将这个非聚集索引表物理存储在磁盘上所需的额外空间.但是,不受非聚集索引数量的限制.

Q2:这是否意味着对非聚集索引列的查询不会导致排序数据?

问题3:此处有一个额外的查找,用于使用叶节点处的指针定位实际的行数据.与聚簇索引相比,这会有多大的性能差异?

锻炼; Tibial:

考虑一个Employee表:

CREATE TABLE Employee
(
PersonID int PRIMARY KEY,
Name varchar(255),
age int,
salary int
); 

现在我创建了一个employee表(创建了employee上的默认聚簇索引).

此表上的两个常见查询仅发生在年龄和工资列上.为简单起见,
我们假设该表不经常更新

例如:

select * from employee where age > XXX;

select * from employee where salary > XXXX and salary < YYYY;

问题4:构建索引的最佳方法是什么,以便这两列上的查询具有相似的性能.如果我在年龄列上的年龄查询上有聚簇索引会更快但是在工资列上会更慢.

问题5:在相关的说明中,我反复看到应该在具有唯一约束的列上创建索引(聚簇和非聚簇).这是为什么?未能做到这一点会发生什么?

非常感谢你
我读的帖子在这里:

http://javarevisited.blogspot.com/2013/08/difference-between-clustered-index-and-nonclustered-index-sql-server-database.html

http://msdn.microsoft.com/en-us/library/ms190457.aspx

Clustered vs Non-Clustered

What do Clustered and Non clustered index actually mean?

What are the differences between a clustered and a non-clustered index?

How does database indexing work?

解决方法:

对于SQL Server

Q1如果聚集索引不是唯一的,则仅需要额外空间. SQL Server将在内部向非唯一聚簇索引添加一个4字节的uniquifier.这是因为它将群集密钥用作非群集索引中的rowid.

Q2可以按顺序读取非聚集索引.这可能有助于您指定订单的查询.它也可能使合并连接具有吸引力.它还有助于范围查询(x< col和y> col).

Q3使用非聚集索引时,SQL Server会执行额外的“书签查找”.但是,只有当它需要一个不在索引中的列时才会这样.另请注意,您可以在索引的叶级别中包含额外的列.如果可以在没有附加查找的情况下使用索引,则将其称为覆盖索引.

如果需要书签查找,则只需扫描整个聚簇索引就可以更快地占用大部分行.级别取决于行大小,密钥大小等.但行的5%是典型的截止.

Q4如果您的应用程序中最重要的事情是尽可能快地完成这两个查询,您可以在它们上创建覆盖索引:

create index IX_1 on employee (age) include (name, salary);
create index IX_2 on employee (salary) include (name, age);

请注意,您不必专门包含群集密钥,因为非聚集索引将其作为行指针.

Q5由于uniquifier,这对于群集密钥比非群集密钥更重要.但真正的问题是索引是否对您的查询具有选择性.想象一下比特值的索引.除非数据分布非常偏差,否则这样的索引不可能用于任何事情.

有关uniquifier的更多信息.想象一下你和一个关于年龄的非唯一聚集索引,以及一个关于薪水的非聚集索引.假设您有以下行:

age | salary | uniqifier
20  | 1000   | 1
20  | 2000   | 2

然后工资指数会找到这样的行

1000 -> 20, 1
2000 -> 20, 2

假设你运行查询select * from employee where salary = 1000,优化器选择使用薪水索引.然后它将从索引查找中找到对(20,1),然后在主数据中查找该值.

标签:clustered-index,non-clustered-index,sql,mysql,indexing
来源: https://codeday.me/bug/20190725/1529767.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有