分析問題
將數(shù)據(jù)庫備份到一臺(tái)測(cè)試的服務(wù)器上,查看一下數(shù)據(jù)庫的數(shù)據(jù)文件和日志文件情況,發(fā)現(xiàn)日志文件比較大,貌似這也是一個(gè)SQL Server 存在的問題,具體原因不清楚,但是解決方法已經(jīng)非常成熟,該問題暫時(shí)不影響使用,先不管它。
上一篇定位了問題,找出了多條Top SQL,其中這條最過分。
exec oa_SWLIST
’glzyf’,
’(s.fileSerialNumber like ’’%%’’ or s.title like ’’%%’’ or s.keywords like ’’%%’’ or s.fileZi like ’’%%’’) and ’,
’ ( ft.userid=’’glzyf’’ ) ’
分析一下這個(gè)存儲(chǔ)過程,我習(xí)慣是先看看SQL語句的結(jié)構(gòu),而不是馬上看執(zhí)行計(jì)劃,或者直接跑語句獲得統(tǒng)計(jì)信息。
ALTER PROCEDURE [dbo].[oa_SWLIST]
@userID varchar(20),
@sql varchar(1000),
@userIDs varchar(1000)
AS
DECLARE @SQL1 nchar(4000) ;
DECLARE @SQL2 nchar(4000) ;
create table #employees(
[id] [int] IDENTITY(1,1) NOT NULL,parentId int,pkId int,status int,title nvarchar(1500),comeOrg nvarchar(100),
fileDate DateTime,fileName nvarchar(4000),filePath nvarchar(4000),readStatus nvarchar(10),optionStatus nvarchar(10),
depId nvarchar(20),urgencyLevel nvarchar(10));
set @SQL1=’insert into #employees (parentId,pkId,status,title,comeOrg,fileDate,fileName,filePath,readStatus,optionStatus,depId,urgencyLevel)
select distinct s.parentId,s.pkId,0,s.title,s.comeOrg,s.fileDate,
s.fileName,s.filePath,ft.readStatus,0,s.remark3,
case
when urgencyLevel=’’普通’’ then 0
when urgencyLevel=’’急件’’ then 1
when urgencyLevel=’’特辦’’ then 2
when urgencyLevel=’’特急件’’ then 3
when urgencyLevel=’’’’ then 4
else 0
end as urgencyLevel
from ShouWen as s ,
FlowTurning as ft where ’+@sql+’ ft.status=0 and ft.type=’’sw’’
and s.pkid=ft.pkid and s.status<>’’4’’ and ’+@userIDs+’ order by urgencyLevel desc,s.filedate desc’
set @SQL2=’insert into #employees (parentId,pkId,status,title,comeOrg,fileDate,
fileName,filePath,readStatus,optionStatus,depId,urgencyLevel)
select distinct s.parentId,s.pkId,1,s.title,s.comeOrg,s.fileDate,
s.fileName,s.filePath,1,l.optionstatus,s.remark3,urgencyLevel
from shouwen as s, log as l where ’+@sql+’ s.status<>’’4’’ and s.pkid in
(
select distinct(mid) from log where uid=’’’+@userID+’’’ and typeid=’’shouwen’’
)and l.mid=s.pkid and uid=’’’+@userID+’’’ and typeid=’’shouwen’’
order by s.fileDate desc’
print (@SQL1);
exec (@SQL1)
print (’+++++++++++++++++++++++++++++++++++’);
print (@SQL2);
exec (@SQL2)
select * from #employees
delete from #employees
從結(jié)果來看該存儲(chǔ)過程其實(shí)就是執(zhí)行了兩條動(dòng)態(tài)SQL,分別存在@SQL1和SQL2。稍微修改了一下存儲(chǔ)過程,加入了一些調(diào)試信息,打開統(tǒng)計(jì)器。
SET STATISTICS IO on;
SET STATISTICS TIME on;
執(zhí)行存儲(chǔ)過程,這里由于信息量比較大。
可見@SQL1的語句耗時(shí)并不多,@SQL2資源占用是非常厲害的。其中 Log 表掃描530次,這個(gè)表的數(shù)據(jù)量有257417條,說大不大,說小也不小了,而且還得掃描530次,唉,啥也不說了,而shouwen這張表就小很多也有25000+條記錄。
我將@SQL2的語句整理出來,去掉那個(gè)討厭的 insert into #employees。
select distinct s.parentId,s.pkId,1,s.title,s.comeOrg,s.fileDate,
s.fileName,s.filePath,1,l.optionstatus,s.remark3,urgencyLevel
from shouwen as s,
log as l
where
(s.fileSerialNumber like ’%%’ or s.title like ’%%’
or s.keywords like ’%%’ or s.fileZi like ’%%’)
and s.status<>’4’
and s.pkid in
(select distinct(mid) from log where uid=’glzyf’ and typeid=’shouwen’)
and l.mid=s.pkid and uid=’glzyf’ and typeid=’shouwen’
order by s.fileDate desc
看看這個(gè)select 語句的執(zhí)行計(jì)劃啦。
以下才是重點(diǎn),兩個(gè)在Log表上面的“聚集索引掃描”:
無論哪個(gè)RDBMS的語句調(diào)優(yōu),絕大部分的情況下都是將執(zhí)行計(jì)劃中的“掃描”轉(zhuǎn)變?yōu)椤安檎摇薄?
將數(shù)據(jù)庫備份到一臺(tái)測(cè)試的服務(wù)器上,查看一下數(shù)據(jù)庫的數(shù)據(jù)文件和日志文件情況,發(fā)現(xiàn)日志文件比較大,貌似這也是一個(gè)SQL Server 存在的問題,具體原因不清楚,但是解決方法已經(jīng)非常成熟,該問題暫時(shí)不影響使用,先不管它。
上一篇定位了問題,找出了多條Top SQL,其中這條最過分。
exec oa_SWLIST
’glzyf’,
’(s.fileSerialNumber like ’’%%’’ or s.title like ’’%%’’ or s.keywords like ’’%%’’ or s.fileZi like ’’%%’’) and ’,
’ ( ft.userid=’’glzyf’’ ) ’
分析一下這個(gè)存儲(chǔ)過程,我習(xí)慣是先看看SQL語句的結(jié)構(gòu),而不是馬上看執(zhí)行計(jì)劃,或者直接跑語句獲得統(tǒng)計(jì)信息。
ALTER PROCEDURE [dbo].[oa_SWLIST]
@userID varchar(20),
@sql varchar(1000),
@userIDs varchar(1000)
AS
DECLARE @SQL1 nchar(4000) ;
DECLARE @SQL2 nchar(4000) ;
create table #employees(
[id] [int] IDENTITY(1,1) NOT NULL,parentId int,pkId int,status int,title nvarchar(1500),comeOrg nvarchar(100),
fileDate DateTime,fileName nvarchar(4000),filePath nvarchar(4000),readStatus nvarchar(10),optionStatus nvarchar(10),
depId nvarchar(20),urgencyLevel nvarchar(10));
set @SQL1=’insert into #employees (parentId,pkId,status,title,comeOrg,fileDate,fileName,filePath,readStatus,optionStatus,depId,urgencyLevel)
select distinct s.parentId,s.pkId,0,s.title,s.comeOrg,s.fileDate,
s.fileName,s.filePath,ft.readStatus,0,s.remark3,
case
when urgencyLevel=’’普通’’ then 0
when urgencyLevel=’’急件’’ then 1
when urgencyLevel=’’特辦’’ then 2
when urgencyLevel=’’特急件’’ then 3
when urgencyLevel=’’’’ then 4
else 0
end as urgencyLevel
from ShouWen as s ,
FlowTurning as ft where ’+@sql+’ ft.status=0 and ft.type=’’sw’’
and s.pkid=ft.pkid and s.status<>’’4’’ and ’+@userIDs+’ order by urgencyLevel desc,s.filedate desc’
set @SQL2=’insert into #employees (parentId,pkId,status,title,comeOrg,fileDate,
fileName,filePath,readStatus,optionStatus,depId,urgencyLevel)
select distinct s.parentId,s.pkId,1,s.title,s.comeOrg,s.fileDate,
s.fileName,s.filePath,1,l.optionstatus,s.remark3,urgencyLevel
from shouwen as s, log as l where ’+@sql+’ s.status<>’’4’’ and s.pkid in
(
select distinct(mid) from log where uid=’’’+@userID+’’’ and typeid=’’shouwen’’
)and l.mid=s.pkid and uid=’’’+@userID+’’’ and typeid=’’shouwen’’
order by s.fileDate desc’
print (@SQL1);
exec (@SQL1)
print (’+++++++++++++++++++++++++++++++++++’);
print (@SQL2);
exec (@SQL2)
select * from #employees
delete from #employees
從結(jié)果來看該存儲(chǔ)過程其實(shí)就是執(zhí)行了兩條動(dòng)態(tài)SQL,分別存在@SQL1和SQL2。稍微修改了一下存儲(chǔ)過程,加入了一些調(diào)試信息,打開統(tǒng)計(jì)器。
SET STATISTICS IO on;
SET STATISTICS TIME on;
執(zhí)行存儲(chǔ)過程,這里由于信息量比較大。
可見@SQL1的語句耗時(shí)并不多,@SQL2資源占用是非常厲害的。其中 Log 表掃描530次,這個(gè)表的數(shù)據(jù)量有257417條,說大不大,說小也不小了,而且還得掃描530次,唉,啥也不說了,而shouwen這張表就小很多也有25000+條記錄。
我將@SQL2的語句整理出來,去掉那個(gè)討厭的 insert into #employees。
select distinct s.parentId,s.pkId,1,s.title,s.comeOrg,s.fileDate,
s.fileName,s.filePath,1,l.optionstatus,s.remark3,urgencyLevel
from shouwen as s,
log as l
where
(s.fileSerialNumber like ’%%’ or s.title like ’%%’
or s.keywords like ’%%’ or s.fileZi like ’%%’)
and s.status<>’4’
and s.pkid in
(select distinct(mid) from log where uid=’glzyf’ and typeid=’shouwen’)
and l.mid=s.pkid and uid=’glzyf’ and typeid=’shouwen’
order by s.fileDate desc
看看這個(gè)select 語句的執(zhí)行計(jì)劃啦。
以下才是重點(diǎn),兩個(gè)在Log表上面的“聚集索引掃描”:
無論哪個(gè)RDBMS的語句調(diào)優(yōu),絕大部分的情況下都是將執(zhí)行計(jì)劃中的“掃描”轉(zhuǎn)變?yōu)椤安檎摇薄?