FSharp Resource Web- F# F#文档 F#新闻 F#专家 F#开发系列教程
SQL Server 性能调优札记之二
2009年02月20日 11时01分03秒
分析问题
将数据库备份到一台测试的服务器上,查看一下数据库的数据文件和日志文件情况,发现日志文件比较大,貌似这也是一个SQL Server 存在的问题,具体原因不清楚,但是解决方法已经非常成熟,该问题暂时不影响使用,先不管它。
上一篇定位了问题,找出了多条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'' ) '
分析一下这个存储过程,我习惯是先看看SQL语句的结构,而不是马上看执行计划,或者直接跑语句获得统计信息。
ALTER PROCEDURE [dbo].[oa_SWLIST] @userID varchar(20), @sql varchar(1000), @userIDs varchar(1000)ASDECLARE @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 0when urgencyLevel=''急件'' then 1when urgencyLevel=''特办'' then 2when urgencyLevel=''特急件'' then 3when urgencyLevel=''限时'' then 4else 0end 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 #employeesdelete from #employees
从结果来看该存储过程其实就是执行了两条动态SQL,分别存在@SQL1和SQL2。我稍微修改了一下存储过程,加入了一些调试信息,打开统计器。
SET STATISTICS IO on; SET STATISTICS TIME on;
执行存储过程,这里由于信息量比较大,我就不贴了,上一张图吧。
可见@SQL1的语句耗时并不多,@SQL2资源占用是非常厉害的。其中 Log 表扫描530次,这个表的数据量有257417条,说大不大,说小也不小了,而且还得扫描530次,唉,啥也不说了,而shouwen这张表就小很多也有25000+条记录。
我将@SQL2的语句整理出来,去掉那个讨厌的 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
看看这个select 语句的执行计划啦。
以下才是重点,两个在Log表上面的“聚集索引扫描”:
无论哪个RDBMS的语句调优,绝大部分的情况下都是将执行计划中的“扫描”转变为“查找”。下一篇讲解如何将“扫描”变为“查找”。
+ 相关文章
- SQL Server 性能调优札记之一 (2009-02-20 11:00:24)
- SQL Server 性能调优札记之三 (2009-02-20 11:01:46)
- 数据库索引-Myshuiyue (2009-03-31 05:01:36)
- SQL性能优化 (2009-04-08 09:34:54)
- SQL Server性能优化的一些简单技巧 (2009-04-21 09:35:30)
- mssql和mysql区别 (2009-05-22 04:35:10)
- 发布MySQL-5.1.30的scws-1.x分词插件 (2009-06-30 11:22:35)
+ 发表评论
- 名称(*)
- 邮箱
- 网站链接
- 验证(*)
-
正文(*)(留言最长字数:1024)
- 记住我,下次回复时不用输入个人信息
- 欢迎参与讨论,请在这里发表您的看法,表达您的观点。
