SQL Server中的联合主键、聚集索引、非聚集索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我们依然可以通过对联合主键中的首列除外的其他列建立非聚集索引来提高性能。
本文将对联合主键、聚集索引、非聚集索引对查询性能的影响举例说明。
步骤一,建立一个测试表,并且插入350万条以上的数据。
/*创建测试数据表*/
create table MyTestTable
(
id varchar(10)not null,
parent varchar(40) not null,
addtime datetime default(getdate()),
intcolumn int default(10),
bitcolumn bit default(1)
)
go
/*添加万条随机字符串测试数据耗时分钟*/
declare @count int=3557643
declare @i int =0
declare @id varchar(10),@parent varchar(40)
while(@i<@count)
begin
select @id=left(newid(),10)
if(@i % 20=0)
begin
select @parent=left(newid(),40)
end
insert MyTestTable(id,parent) values(@id,@parent)
select @i=@i+1
end
go
步骤二,不建立任何索引查询测试
/*未建立索引时的查询*/
declare @beginTime datetime =getdate()
declare @elapsedSecond int =0
select * from MyTestTable where parent='DD7D9F34-3A9C-43CA-836B-F2BABD78CE70' and id='103ACE5C-7'
select @elapsedSecond=DATEDIFF(MICROSECOND,@beginTime,GETDATE())
print '未建立索引时查找数据消耗微秒数'
print @elapsedSecond
select @beginTime=GETDATE()
select * from MyTestTable where parent='F535C18F-BD48-4D45-88DF-9653BB9B422D'
select @elapsedSecond=DATEDIFF(MICROSECOND,@beginTime,GETDATE())
print '未建立索引时查找第二列数据消耗微秒数'
print @elapsedSecond
--(1 row(s) affected)
--未建立索引时查找数据消耗微秒数
--530000
--(20 row(s) affected)
--未建立索引时查找第二列数据消耗微秒数
--500000
从执行结果我们可以看出,当没有索引的时候,SQL Server会遍历整个表,因此需要很长的时间。
步骤三,建立联合主键(会自动创建聚集索引)并查询测试
go
/*建立联合主键*/
alter table MyTestTable add constraint PK_id_parent primary key(id asc,parent asc)
/*建立索引后的查询*/
declare @beginTime datetime =getdate()
declare @elapsedSecond int =0
select * from MyTestTable where parent='DD7D9F34-3A9C-43CA-836B-F2BABD78CE70' and id='103ACE5C-7'
select @elapsedSecond=DATEDIFF(MICROSECOND,@beginTime,GETDATE())
print '建立索引时查找数据消耗微秒数'
print @elapsedSecond
select @beginTime=GETDATE()
select * from MyTestTable where parent='F535C18F-BD48-4D45-88DF-9653BB9B422D'
select @elapsedSecond=DATEDIFF(MICROSECOND,@beginTime,GETDATE())
print '建立索引后查找第二列数据消耗微秒数'
print @elapsedSecond
go
--(1 row(s) affected)
--建立索引时查找数据消耗微秒数
--0
--(20 row(s) affected)
--建立索引后查找第二列数据消耗微秒数
--500000
从上面看出,建立联合主键后,查询第一列或者同时查询两列(and关系)速度会非常的快,小于1微妙,但查询联合主键的第二列的时候却特别的慢,因为无法通过索引查询。
步骤四,给联合主键的第二列建立非聚集索引,并且测试
go
/*给第二列创建非聚集索引*/
create index index_parent on MyTestTable(parent asc)
declare @beginTime datetime =getdate()
declare @elapsedSecond int =0
select * from MyTestTable where parent='DD7D9F34-3A9C-43CA-836B-F2BABD78CE70' and id='103ACE5C-7'
select @elapsedSecond=DATEDIFF(MICROSECOND,@beginTime,GETDATE())
print '为第二列建立索引时查找数据消耗微秒数'
print @elapsedSecond
select @beginTime=GETDATE()
select * from MyTestTable where parent='9A75DC47-DDF7-4922-9179-E87B91FE3921'
select @elapsedSecond=DATEDIFF(MICROSECOND,@beginTime,GETDATE())
print '为第二列建立索引后查找第二列数据消耗微秒数'
print @elapsedSecond
--(1 row(s) affected)
--为第二列建立索引时查找数据消耗微秒数
--0
--(20 row(s) affected)
--为第二列建立索引后查找第二列数据消耗微秒数
--0
从执行结果可以看出,建立索引后,查询第二列的速度也非常的快了。
总结
一般情况下,对于一个表T,联合主键(A,B),下列情况的查询时,SQL Server 可以从索引中查询,速度较快:
select * from T where A=Value and B=Value
select * from T where B=Value and A=Value
select * from T where A=Value
下面的查询不会经过索引,速度会比较的慢
select * from T where A=Value or B=Value
select * from T where B=Value
SQL Server中的联合主键、聚集索引、非聚集索引的更多相关文章
- SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...
- SQL Server 创建表 添加主键 添加列常用SQL语句
--删除主键 alter table 表名 drop constraint 主键名 --添加主键 alter table 表名 add constraint 主键名 primary key(字段名1, ...
- SQL Server 创建表 添加主键 添加列常用SQL语句【转】
--删除主键alter table 表名 drop constraint 主键名--添加主键alter table 表名 add constraint 主键名 primary key(字段名1,字段名 ...
- JPA学习---第十二节:JPA中的联合主键
1.定义实体类,代码如下: (1).将联合主键放到一个类中,代码如下: package learn.jpa.entity; import java.io.Serializable; import ja ...
- SQL SERVER大话存储结构(2)_非聚集索引如何查找到行记录
如果转载,请注明博文来源: www.cnblogs.com/xinysu/ ,版权归 博客园 苏家小萝卜 所有.望各位支持! 1 行记录如何存储 这里引入两个 ...
- SQL Server(MySql)中的联合主键(联合索引) 索引分析
最近有人问到这个问题,之前也一直没有深究联合索引具体使用逻辑,查阅多篇文章,并经过测试,得出一些结论 测试环境:SQL Server 2008 R2 测试结果与MySql联合索引查询机制类似,可以认为 ...
- sql server 建表,主键与外键约束
主键: 能唯一区分表中每一行 外键:为某表的一列,是另一个表的主键,外键定义了两表之间的联系 商品类别表 use eshopgocreate table category( name varchar( ...
- SQL server 获得 表的主键,自增键
主键: @tableName --表名 @id ---表对应的id SELECT SYSCOLUMNS.name FROM SYSCOLUMNS,SYSOBJECTS,SYSINDEXES,SYSIN ...
- SQL Server中的聚集索引(clustered index) 和 非聚集索引 (non-clustered index)
本文转载自 http://blog.csdn.net/ak913/article/details/8026743 面试时经常问到的问题: 1. 什么是聚合索引(clustered index) / ...
随机推荐
- python16_day07【Socket网络编程】
一.简介 1.理解C/S,B/S 2.IOS七层模型(http://www.cnblogs.com/linhaifeng/articles/5937962.html) 二.什么是Socket 我们看看 ...
- LeetCode:N叉树的层次遍历【429】
LeetCode:N叉树的层次遍历[429] 题目描述 给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右,逐层遍历). 例如,给定一个 3叉树 : 返回其层序遍历: [ [1], [3,2, ...
- 102. Binary Tree Level Order Traversal ------层序遍历
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to righ ...
- hdu 1686 Oulipo kmp算法
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目: Problem Description The French author George ...
- Bootstrap总结二
参考我的博客:http://www.isedwardtang.com/2017/09/01/bootstrap-primer-2/
- docker 中安装PHP扩展
可以通过两种方式实现 1.pecl pdo_msql 方式二: docker-php-ext-install pdo pdo_mysql 如果报 /usr/local/bin/docker-php-e ...
- LigerUI v1.2.4 LigerGrid默认样式 工具条背景白色
修改Aqua的ligerui-grid.css .l-panel-topbar 样式 修改为: .l-panel-topbar{padding: 0;background: #CEDFEF url(' ...
- ES6 完全使用手册
前言 这里的 "ES6" 泛指 ES5 之后的新语法 这里的 "完全" 是指本文会不断更新 这里的 "使用" 是指本文会展示很多 ES6 的 ...
- 什么是“欧几里德范数”(Euclidean norm)?
x是n维向量(x1,x2,…,xn),||x||=根号(|x1|方+|x2|方+…+|xn|方) 补充:开平方,跟几何一样
- 如何理解 Python 中的__init__
转自https://www.zhihu.com/question/46973549/answer/103805810 定义类的时候,若是添加__init__方法,那么在创建类的实例的时候,实例会自动调 ...