死锁,上图,高手进

shiyueyangfeng 2014-08-25 03:10:56
1.最近公司的服务器从SQL SERVER 2000升级到了SQL SERVER 2008,奇怪的时,之前没有出现的死锁的情况;
2.公司使用的系统是CRM系统,
2.目前用户并发数大概在30-60人以内,每天都是死锁几次,如图:


左边的图是被丢掉的事务,SQL语句是个查询,是对客户数据的一个分页查看:
Select top 100 PID,LastContactTextNew,Remark,CreateDate,CustCode,CustName From vCu_Customer Left Join Sy_Share on (vCu_Customer.PID=SharePID and ShareTableName='Cu_Customer' and shareuserid=246) where vCu_Customer.PID not in(Select top 0 vCu_Customer.PID From vCu_Customer Left Join Sy_Share on (vCu_Customer.PID=SharePID and ShareTableName='Cu_Customer' and shareuserid=246) where ((1=1) and (CustPublicType is null or CustPublicType=0) and (isSaleOK=0 or isSaleOK is null) ) And (owner = 246 or Share=1 or shareuserid=246)) and ((1=1) and (CustPublicType is null or CustPublicType=0) and (isSaleOK=0 or isSaleOK is null) ) And (owner = 246 or Share=1 or shareuserid=246) AND (CustPublicType=0 OR CustPublicType IS Null)
说明:这个SQL有点复杂,是对客户表的一个查询,带权限的,这条语句在查询分析器里是1秒就查出数据的;

右边的图是对联系人的一个修改:
update cu_contact set ContName='李福财
',Dept=0,Job='',FamilyTel='',WorkTel='',MobileTel='13609005309
',Birthday=null,Email='',QQ='',Msn='',Sex=0,PhoneSort=1 where PID=380137

这些死锁大多都是在修改联系人时,出现的,因为vCu_Customer(客户表)关联了联系人表,所以在查询时,会访问联系人表,
请大家帮小弟分析一下,这个是会是什么原因造成死锁的
...全文
209 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2014-08-26
  • 打赏
  • 举报
回复
现在是2008,可以用ROW_NUMBER了。

升级了性能下降很正常,你原样照搬的设计,又没有用到可以提升性能的新功能。
新版本通常是“更安全更可靠”,多做些检测之类的也不奇怪。
hleb231 2014-08-26
  • 打赏
  • 举报
回复
你要更新数据 直接关联物理表。 统计报表用视图。
shiyueyangfeng 2014-08-26
  • 打赏
  • 举报
回复
我觉得就是很奇怪,我的UPDATE的过程是很快的,SELECT过程也是很快的,怎么就会出现死锁呢,而且之前使用sql 2000时,也没有出现过死锁,反而在升级到2008后,出现了死锁! 这个情况难道没有人遇到过吗?
shiyueyangfeng 2014-08-26
  • 打赏
  • 举报
回复
楼上的兄台,因为这套产品不仅仅是给公司用的,也会给客户用,给客户用,我们是用SQL SERVER 2000的,2000是没有row_number的
Tiger_Zhao 2014-08-26
  • 打赏
  • 举报
回复
引用 4 楼 shiyueyangfeng 的回复:
vCu_Customer是一个视图,如下: SELECT dbo.Cu_Customer.PID, dbo.Cu_Customer.CustCode, dbo.Cu_Customer.CustName, dbo.Cu_Customer.CustOtherName, dbo.Cu_Customer.Tel, dbo.Cu_Customer.Fax, dbo.Cu_Customer.Industry, dbo.Cu_Customer.XinYong, dbo.CU_Contact.ContName, dbo.CU_Contact.PID AS ContID, dbo.CU_Contact.Dept, dbo.CU_Contact.Job, dbo.CU_Contact.FamilyTel, dbo.CU_Contact.WorkTel, dbo.CU_Contact.MobileTel, FROM dbo.Cu_Customer INNER JOIN dbo.CU_Contact ON dbo.Cu_Customer.PID = dbo.CU_Contact.CustID WHERE (dbo.CU_Contact.Base = 1)
A)不要用 vCu_Customer 视图,直接关联 Cu_Customer 和 CU_Contact 进行查询。 用视图虽然写起来简便,但是由于是全表选取,只要有一条记录被锁定,就会等待。所以用视图会加大冲突几率。 B)如果不是 SQL Server Compact Edition,也可以考虑视图中用 WITH (NOLOCK),这样不等待,但是进行的是脏读,不能保证数据一致性。
引用 5 楼 shiyueyangfeng 的回复:
NOT IN (SELECT TOP 0 vcu_customer.pid -- 这里怎么回事啊,存心折腾 SQL 是吧! 因为这个地方是一个分页:也就是第一页吧,如果是第二页的话,如下: NOT IN (SELECT TOP 100 vcu_customer.pid 这个可以不管他的。
分页可以用 ROW_NUMBER(),NOT IN 是非常没有效率的方式。
shiyueyangfeng 2014-08-25
  • 打赏
  • 举报
回复
引用 2 楼 liuqian4243 的回复:
数据量具大,更新和查询时,用的时间太长了吧.
这个我做过测试,一秒钟数据就出来了,应该不是这个问题;没办法,要知道,管理软件的确会有多个查询的,而且查询还带着权限
shiyueyangfeng 2014-08-25
  • 打赏
  • 举报
回复
NOT IN (SELECT TOP 0 vcu_customer.pid -- 这里怎么回事啊,存心折腾 SQL 是吧! 因为这个地方是一个分页:也就是第一页吧,如果是第二页的话,如下: NOT IN (SELECT TOP 100 vcu_customer.pid 这个可以不管他的。
shiyueyangfeng 2014-08-25
  • 打赏
  • 举报
回复
引用 1 楼 Tiger_Zhao 的回复:
代码都不格式化一下,差评!
SELECT TOP 100 pid,
               lastcontacttextnew,
               remark,
               createdate,
               custcode,
               custname
FROM   vcu_customer
       LEFT JOIN sy_share
         ON (vcu_customer.pid = sharepid
             AND sharetablename = 'Cu_Customer'
             AND shareuserid = 246)
WHERE  vcu_customer.pid NOT IN (SELECT TOP 0 vcu_customer.pid -- 这里怎么回事啊,存心折腾 SQL 是吧!
                                FROM   vcu_customer
                                       LEFT JOIN sy_share
                                         ON (vcu_customer.pid = sharepid
                                             AND sharetablename = 'Cu_Customer'
                                             AND shareuserid = 246)
                                WHERE  ((1 = 1)
                                        AND (custpublictype IS NULL 
                                              OR custpublictype = 0)
                                        AND (issaleok = 0
                                              OR issaleok IS NULL))
                                       AND (owner = 246
                                             OR share = 1
                                             OR shareuserid = 246))
       AND ((1 = 1)
            AND (custpublictype IS NULL 
                  OR custpublictype = 0)
            AND (issaleok = 0
                  OR issaleok IS NULL))
       AND (owner = 246
             OR share = 1
             OR shareuserid = 246)
       AND (custpublictype = 0
             OR custpublictype IS NULL)
还有看不出来和 update cu_contact 的关系啊!
不好意思啊,没格式化; vCu_Customer是一个视图,如下: SELECT dbo.Cu_Customer.PID, dbo.Cu_Customer.CustCode, dbo.Cu_Customer.CustName, dbo.Cu_Customer.CustOtherName, dbo.Cu_Customer.Tel, dbo.Cu_Customer.Fax, dbo.Cu_Customer.Industry, dbo.Cu_Customer.XinYong, dbo.CU_Contact.ContName, dbo.CU_Contact.PID AS ContID, dbo.CU_Contact.Dept, dbo.CU_Contact.Job, dbo.CU_Contact.FamilyTel, dbo.CU_Contact.WorkTel, dbo.CU_Contact.MobileTel, FROM dbo.Cu_Customer INNER JOIN dbo.CU_Contact ON dbo.Cu_Customer.PID = dbo.CU_Contact.CustID WHERE (dbo.CU_Contact.Base = 1)
最爱午夜 2014-08-25
  • 打赏
  • 举报
回复
你先把select语句执行一下, 然后把select语句中的1=1和or 去掉再执行一下。 然后你就明白为什么会有死锁了。 太多的or导致查询分析器生成复杂的执行计划。
Ny-6000 2014-08-25
  • 打赏
  • 举报
回复
数据量具大,更新和查询时,用的时间太长了吧.
Tiger_Zhao 2014-08-25
  • 打赏
  • 举报
回复
代码都不格式化一下,差评!
SELECT TOP 100 pid,
lastcontacttextnew,
remark,
createdate,
custcode,
custname
FROM vcu_customer
LEFT JOIN sy_share
ON (vcu_customer.pid = sharepid
AND sharetablename = 'Cu_Customer'
AND shareuserid = 246)
WHERE vcu_customer.pid NOT IN (SELECT TOP 0 vcu_customer.pid -- 这里怎么回事啊,存心折腾 SQL 是吧!
FROM vcu_customer
LEFT JOIN sy_share
ON (vcu_customer.pid = sharepid
AND sharetablename = 'Cu_Customer'
AND shareuserid = 246)
WHERE ((1 = 1)
AND (custpublictype IS NULL
OR custpublictype = 0)
AND (issaleok = 0
OR issaleok IS NULL))
AND (owner = 246
OR share = 1
OR shareuserid = 246))
AND ((1 = 1)
AND (custpublictype IS NULL
OR custpublictype = 0)
AND (issaleok = 0
OR issaleok IS NULL))
AND (owner = 246
OR share = 1
OR shareuserid = 246)
AND (custpublictype = 0
OR custpublictype IS NULL)

还有看不出来和 update cu_contact 的关系啊!

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧