SQL知识整理二:锁、游标、索引
锁
锁的模式
锁模式 |
描述 |
共享(S) |
用于不更改或不更新数据(只读操作),如SELECT语句 |
更新(U) |
用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。 |
排它(X) |
用于数据修改操作,例如INSERT、UPDATE或DELETE。确保不会同时对同一资源进行多重更新 |
意向 |
SQL Server有在资源的低层获得共享锁或排它锁的意向意向锁的类型为:意向共享(IS)、意向排它(IX)以及意向排它共享(SIX) |
架构 |
在执行依赖于表架构的操作时使用。架构锁的类型为:架构修改(Sch-M)和架构稳定(Sch-S) |
大容量更新(BU) |
向表中大容量复制数据并指定了TABLOCK提示时使用 |
死锁 死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。
死锁的四个必要条件
互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源
死锁的处理方法
查看那个spid处于wait状态,然后用kill spid来干掉(即破坏死锁的第四个必要条件:循环等待)。
使用SET LOCK_TIMEOUT timeout_period(单位为毫秒)来设定锁请求超时。默认情况下,数据库没有超时期限(timeout_period值为-1,可以用SELECT @@LOCK_TIMEOUT来查看该值,即无限期等待)。
SQL Server内部有一个锁监视器线程执行死锁检查,锁监视器对特定线程启动死锁搜索,检测到死锁后,数据库引擎选择运行回滚开销最小的事务的会话作为死锁牺牲品回滚死锁牺牲品的事务并释放该事务持有的所有锁,使其他线程的事务可以请求资源并继续运行。
游标
游标定义:
可以对一个select的结果集进行处理,或是不需要全部处理,就会返回一个对记录集进行处理之后的结果。
游标实际上是一种能从多条数据记录的结果集中每次提取一条记录的机制。游标可以完成:
# 允许定位到结果集中的特定行
# 从结果集的当前位置检索一行或多行数据
# 支持对结果集中当前位置的进行修改
由于游标是将记录集进行一条条的操作,所以这样给服务器增加负担,一般在操作复杂的结果集的情况下,才使用游标。SQL Server 2005有三种游标:T-SQL游标、API游标、客户端游标。
游标的基本操作
游标的基本操作有定义游标、打开游标、循环读取游标、关闭游标、删除游标。
A、 定义游标
declare cursor_name --游标名称
cursor [local | global] --全局、局部
[forward only | scroll] --游标滚动方式
[read_only | scroll_locks | optimistic] --读取方式
for select_statements --查询语句
[for update | of column_name ...] --修改字段
参数:
forward only | scroll:前一个参数,游标只能向后移动;后一个参数,游标可以随意移动
read_only:只读游标
scroll_locks:游标锁定,游标在读取时,数据库会将该记录锁定,以便游标完成对记录的操作
optimistic:该参数不会锁定游标;此时,如果记录被读入游标后,对游标进行更新或删除不会超过
B、 打开游标
open cursor_name;
游标打开后,可以使用全局变量@@cursor_rows显示读取记录条数
C、 检索游标
fetch cursor_name;
检索方式如下:
fetch first; 读取第一行
fetch next; 读取下一行
fetch prior; 读取上一行
fetch last; 读取最后一行
fetch absolute n; 读取某一行
如果n为正整数,则读取第n条记录
如果n为负数,则倒数提取第n条记录
如果n为,则不读取任何记录
fetch pelative n
如果n为正整数,则读取上次读取记录之后第n条记录
如果n为负数,则读取上次读取记录之前第n条记录
如果n为,则读取上次读取的记录
D、 关闭游标
close cursor_name;
E、 删除游标
deallocate cursor_name;
游标操作示例
--创建一个游标
declare cursor_stu cursor scroll for
select id, name, age from student;
--打开游标
open cursor_stu;
--存储读取的值
declare @id int,
@name nvarchar(20),
@age varchar(20);
--读取第一条记录
fetch first from cursor_stu into @id, @name, @age;
--循环读取游标记录
print '读取的数据如下:';
--全局变量
while (@@fetch_status = 0)
begin
print '编号:' + convert(char(5), @id) + ', 名称:' + @name + ', 类型:' + @age;
--继续读取下一条记录
fetch next from cursor_stu into @id, @name, @age;
end
--关闭游标
close area_cursor; --删除游标
--deallocate area_cursor;
索引
聚集索引定义:
聚簇索引即建立在聚簇上的索引,创建聚簇索引时,需要对已有表数据重新进行排序(若表中已有数据),即删除原始的表数据后再将排序结果按物理顺序插回,故聚簇索引建立完毕后,建立聚簇索引的列中的数据已经全部按序排列。
一个表中只能包含一个聚簇索引,但该索引可以包含多个列。
B-树索引中,聚簇索引的叶层就是数据页。
聚集索引最佳实践:
首先创建聚集索引
聚集索引键最好是唯一值
聚集索引上的列需要足够短,检索一定范围和预先排序数据时使用,因为聚集索引的叶子与数据页面相同,索引顺序也是数据物理顺序,读取数据时,磁头是按照顺序读取,而不是随机定位读取数据
在频繁更新的列上不要设计聚集索引,他将导致所有的非聚集所有的更新,阻塞非聚集索引的查询
不要使用太长的关键字,因为非聚集索引实际包含了聚集索引值
不要在太多并发度高的顺序插入,这将导致页面分割,设置合理的填充因子是个不错的选择
聚集索引示例:
CREATE CLUSTERED INDEX IX_tb_heap_test_id ON dbo.tb_heap_test (id) WITH (ONLINE=ON)
非聚集索引定义:
非聚簇索引类似书本索引,索引与数据存放在不同的物理区域,建立非聚簇索引时数据本身不进行排序。一个表中科含多个非聚簇索引。
B-树索引中,非聚簇索引的叶层仍是索引页,其以指针指向数据页实际存储位置。
非聚集索引最佳实践
频繁更新的列,不适合做聚集索引,但可以做非聚集索引
宽关键字,例如很宽的一列或者一组列,不适合做聚集索引的列可作非聚集索引列
检索大量的行不宜做非聚集索引,但是可以使用覆盖索引来消除这种影响
非聚集索引示例:
CREATE INDEX IX_tb_clustered_update_ID ON dbo.tb_clustered_update (ID) WITH (ONLINE=ON)
非聚集与聚集用法之比较
检索的数据行
一般地,检索数据量大的一般使用聚集索引,因为聚集索引的叶子页面与数据页面在相同。相反,检索少量的数据可能非聚集索引更有利,但注意书签查找消耗资源的力度,不过可考虑覆盖索引解决这个问题。
数据是否排序
如果数据需要预先排序,需要使用聚集索引,若不需要预先排序就那就选择聚集索引。
索引键的宽度
索引键如果太宽,不仅会影响数据查询性能,还影响非聚集索引,因此,若索引键比较小,可以作为聚集索引,如果索引键够大,考虑非聚集索引,如果很大的话,可以用INCLUDE创建覆盖索引
列更新的频度
列更新频率高的话,应该避免考虑所用非聚集索引,否则可考虑聚集索引。
书签查找开销
如果书签查找开销较大,应该考虑聚集索引,否则可使用非聚集索引,更佳是使用覆盖索引,不过得根据具体的查询语句而看
覆盖索引
覆盖索引可显著减少查询的逻辑读次数,使用INCLUDE语句添加列的方式更容易实现,他不仅减小索引中索引列的数据,还可以减少索引键的大小,原因是包含列只保存在索引的叶子级别上,而不是索引的叶子页面。覆盖索引充当一个伪的聚集索引。覆盖索引还能够有效的减少阻塞和死锁的发生,与聚集索引类似,因为聚集索引值发生一次锁,非覆盖索引可能发生两次,一次锁数据,一次锁索引,以确保数据的一致性。覆盖索引相当于数据的一个拷贝,与数据页面隔离,因此也只发生一次锁。
覆盖索引示例:
CREATE INDEX IX_IX_tb_booklookup_name_type_other ON dbo.tb_booklookup (name) INCLUDE ([type],other) WITH ( ONLINE=ON )
SQL知识整理二:锁、游标、索引的更多相关文章
- PL/SQL 编程(二)游标、存储过程、函数
游标--数据的缓存区 游标:类似集合,可以让用户像操作数组一样操作查询出来的数据集,实质上,它提供了一种从集合性质的结果中提取单条记录的手段. 可以将游标形象的看成一个变动的光标,他实质上是一个指针, ...
- 数据库知识整理<二>
又继续写的博客,希望自己能坚持每天写博客.分享自己的点滴,对自己成长有帮助.今天下午高强度打了三个小时篮球,小腿都抽筋了.很爽,失落的心情似乎变得开明了一些.想到了一句话:“像SB式的坚持总会有好的收 ...
- SQL知识整理三:变量、全局变量、视图、事务、异常
变量 1.局部变量的声明(一个@) declare @n int --声明变量关键字为declare 然后@加变量名 后面是变量类型 declare @s varchar(36) 2 ...
- SQL知识整理一:触发器、存储过程、表变量、临时表
触发器 触发器的基础知识 create trigger tr_name on table/view {for | after | instead of } [update][,][insert][,] ...
- SQL语句整理(二) 数据定义语言DDL
前言: 这是我学数据库时整理的学习资料,基本上包括了所以的SQL语句的知识点. 我的教材是人大王珊老师的<数据库系统概论>. 因为是手打的,所以会用一些细节打错了,但都挺明显也不多(考完试 ...
- sql优化整理(二)
对于连接查询,EXPLAIN的extra字段出现using join buffer,表示使用了连接缓存,保证JOIN语句中被驱动表上JOIN条件字段已经添加索引: LEFT JOIN 条件用于确定如何 ...
- TFS二次开发、C#知识点、SQL知识总结目录
TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一个实例 TFS二次开发系列:四.TFS二次开发Wor ...
- TFS二次开发、C#知识点、SQL知识
TFS二次开发.C#知识点.SQL知识总结目录 TFS二次开发系列 TFS二次开发系列:一.TFS体系结构和概念 TFS二次开发系列:二.TFS的安装 TFS二次开发系列:三.TFS二次开发的第一 ...
- Sql Server数据库性能优化之索引
最近在做SQL Server数据库性能优化,因此复习下一索引.视图.存储过程等知识点.本篇为索引篇,知识整理来源于互联网. 索引加快检索表中数据的方法,它对数据表中一个或者多个列的值进行结构排序,是数 ...
随机推荐
- layoutSubviews
- Leetcode: Circular Array Loop
You are given an array of positive and negative integers. If a number n at an index is positive, the ...
- Android JNI 本地开发接口
前言 我们为什么要用JNI --> 高效.扩展 高效:Native code效率高,数学运算,实时渲染的游戏上,音视频处理 (极品飞车,opengl,ffmpeg,文件压缩,图片处理-) 扩展: ...
- jQuery ajax的traditional参数的作用///////////////////////////////////zzzzzzzzzzz
jQuery ajax的traditional参数的作用 i33 发布时间: 2013/04/03 10:05 阅读: 9859 收藏: 9 点赞: 1 评论: 0 一般的,可能有些人在一个参数有多个 ...
- Android隐藏状态栏、导航栏
Android隐藏状态栏.导航栏 private void hideStatusNavigationBar(){ if(Build.VERSION.SDK_INT<16){ this.getWi ...
- maven官方库中没有oracle jdbc驱动的问题解决
1.找到可用的oracle jdbs驱动jar包文件,放置到指定目录(可根据实际自定义) D:\jdbc\ojdbc14.jar 2.安装好maven,主要是配置好环境变量 MAVEN_HOME='指 ...
- SQL语句增加字段、修改字段、修改类型、修改默认值
一.修改字段默认值 alter table 表名 drop constraint 约束名字 ------说明:删除表的字段的原有约束 alter table 表名 add constraint 约 ...
- 浅谈JDBC编程
一.概述 1.为什么要用JDBC 数据库是程序不可或缺的一部分,每一个网站和服务器的建设都需要数据库.对于大多数应用程序员(此处不包含数据库开发人员)来说,我们更多的不是在DBMS中对数据库进行操纵, ...
- 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数017·point点函数
<zw版·Halcon-delphi系列原创教程> Halcon分类函数017·point点函数 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号“**”,替换:“p ...
- 第一次写这么长的js
是公司一个项目,要求显示不同的sku,然后根据sku组合显示不同的价格区间,根据填写的数量落在哪个价格区间,然后进行计算.实际截图如下: 前端JS如下: <script type="t ...