LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

由一个大写N造成的SQL Server死锁

admin
2010年12月25日 21:47 本文热度 3616

   SQL Server死锁的问题断断续续追踪了两三个星期,终于有个初步的判断:有一个SELECT语句和一个UPDATE语句需要获取大量的锁。死锁应该与之相关。


  应用程序在SQL中为每个传入的字符串参数加了N,表示是unicode字符串。在参数与相应的列进行匹配的时候,如果该列不是NVARCHAR而是VARCHAR类型,则SQL Server要对该列的数据进行转换,由于此转换而导致不能使用索引,会获取大量的键锁、页锁。如果几个这样的SQL同时执行则容易死锁。


  比如这样几句SQL:

declare @P1 int
set @P1=14
exec sp_prepexec @P1 output, N
'@P1 nvarchar(4000)', N'SELECT CMDOCUMENTS.*,
CMDOCTYPES.DOCTYPENAME, CMDOCCONTENTS.CONTENTSIZE, CMDOCCONTENTS.MIMETYPE
FROM CMDOCUMENTS INNER JOIN CMDOCTYPES ON CMDOCUMENTS.DOCTYPEID
= CMDOCTYPES.DOCTYPEID LEFT OUTER
JOIN CMDOCCONTENTS ON CMDOCUMENTS.DOCID
= CMDOCCONTENTS.DOCID WHERE CMDOCUMENTS.DOCID = @P1
ORDER BY CMDOCUMENTS.DOCNAME ASC
', N'c373e90a87fa3a628f6acd567805f1f0'
select @P1


  这是用事件探查器跟踪到的。


  其中只有SELECT....是在java应用中写的SQL,前面的declare、set、exec以及后面的select @P1都应该是jdbc生成的。declare @P1 int声明了一个int变量P1,set @P!=NULL 把P1赋值为空,exec sp_prepexec ....是执行SQL Server的存储过程sp_prepexec。@P1是一个输出参数,在存储过程执行后,P1会得到SQL Server分配的句柄。之后就可以用exec sp_execute引用这个句柄来再次执行此SQL。比如:

exec sp_execute 450, N'c373e90a87fa3a5f8f6acd567805f1f0', 2


  这就是执行一个前面已分配句柄的SQL,句柄是450,后面是SQL中需要使用的参数。


  好,现在说N。前面的几个SQL中可以看到在字符串参数值的前面有一个大写的N,它的含义是表明后面引号里的字符串是unicode,如果我没判断错的话,应该就是UTF-8。


  为什么能判断出有了这个N之后就会获取大量的锁呢?是借助于查询分析器。


  我把以下SQL贴到查询分析器中

SELECT * FROM CMDOCUMENTS WHERE CMDOCUMENTS.DOCID = N'c373e90a87fa3a7c8f6acd567805f1f0'


  然后“显示估计的查询计划”在CMDOCUMENTS.PK_...中看到对全部的索引做了扫描(scan),还有“成本100%”,并且其中“参数:”一栏的内容引起了我的怀疑,内容如下:

OBJECT:([v23test83].[v23test83].[CMDOCUMENTS].[PK_CMDOCUMENTS]),WHERE(Convert([CMDOCUMENTS].[DOCID])=[@1])


  可以看到WHERE后面有对列DOCID使用了个函数convert,一般的数据库,如果一旦对列使用了函数就无法使用建立在该列上的索引,除非建立的是函数索引。


  看表结构,DOCID是VARCHAR类型的。


  把N去掉,再做分析

SELECT * FROM CMDOCUMENTS WHERE CMDOCUMENTS.DOCID = 'c373e90a87fa3a7c8f6acd567805f1f0'


  仍然是“成本100%”,但是convert不见了。


  使用事件探查器跟踪。有N的情况下,此查询会获取大量的锁。没有N的情况下,只获取非常少量的锁。如果不去掉N,但把DOCID改为NVARCHAR类型,查询也不会获取大量的锁。所以在SQL Server中使用N可要慎重。


该文章在 2010/12/25 21:47:05 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved