sql 2000 CPU常达99% 求解决方案 跟sql 优化方法 我是做ASP网站开发的数据库有一张表有近200万条数据我觉得最可能是查询这张表时出的问题我想知道数据库的cpu占用跟sql事件跟踪器里看到的cpu占用时间 、reads等有什么关系。这些数值在哪个范围内是允许的可接受的,如果超出了该怎么优化?我目前的优化工作主要做了 建了聚集索引,使用存储过程期待高手进来 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 电脑应该没感染病毒 数据分离目前还没去考虑 因为是会员表 我想200W也不是很多吧索引我已经在使用了能解答下我下面的问题吗我想知道数据库的cpu占用跟sql事件跟踪器里看到的cpu占用时间 、reads等有什么关系。这些数值在哪个范围内是允许的可接受的,如果超出了该怎么优化? 如果排除了以上因素,跟踪一下是什么SQL查询时导致CPU占用100%很有可能是效率极低的SQL查询时导致的比如:是否有cross join 类型的查询 有个分页存储过程 一运行cpu就100%不过查询速度挺快的 近200万的数据 每页显示20条 基本上都在1秒以下并且我也没找到更好的 优化方法 现在不存储过程贴出来 希望高人能帮我分析优化下CREATE PROCEDURE fenye(@RecordCount int =0 output,@Tables varchar(1000),@PrimaryKey varchar(100),@Sort varchar(200) = NULL,@CurrentPage int = 1,@PageSize int = 10,@Fields varchar(1000) = '*',@Filter varchar(1000) = NULL,@Group varchar(1000) = NULL)AS/*默认排序*/DECLARE @Counts intDECLARE @pageCount intIF @Sort IS NULL OR @Sort = ''SET @Sort = @PrimaryKeyDECLARE @SortTable varchar(100)DECLARE @SortName varchar(100)DECLARE @strSortColumn varchar(200)DECLARE @operator char(2)DECLARE @type varchar(100)DECLARE @prec intDECLARE @strtemp nvarchar(1000)/*设定排序语句.*/ IF CHARINDEX('DESC',@Sort)>0BEGINSET @strSortColumn = REPLACE(@Sort, 'DESC', '')SET @operator = '<='ENDELSEBEGINIF CHARINDEX('ASC', @Sort) = 0SET @strSortColumn = REPLACE(@Sort, 'ASC', '')SET @operator = '>='ENDIF CHARINDEX('.', @strSortColumn) > 0BEGINSET @SortTable = SUBSTRING(@strSortColumn, 0, CHARINDEX('.',@strSortColumn))SET @SortName = SUBSTRING(@strSortColumn, CHARINDEX('.',@strSortColumn) + 1, LEN(@strSortColumn))ENDELSEBEGINSET @SortTable = @TablesSET @SortName = @strSortColumnEND/*设定排序字段类型.*/ SELECT @type=t.name, @prec=c.precFROM sysobjects o JOIN syscolumns c on o.id=c.idJOIN systypes t on c.xusertype=t.xusertypeWHERE o.name = @SortTable AND c.name = @SortNameIF CHARINDEX('char', @type) > 0SET @type = @type + '(' + CAST(@prec AS varchar) + ')'DECLARE @strPageSize varchar(50)DECLARE @strStartRow varchar(50)DECLARE @strFilter varchar(1000)DECLARE @strSimpleFilter varchar(1000)DECLARE @strGroup varchar(1000)/*筛选以及分组语句.*/IF @Filter IS NOT NULL AND @Filter != ''BEGINSET @strFilter = ' WHERE ' + @Filter + ' 'SET @strSimpleFilter = ' AND ' + @Filter + ' 'ENDELSEBEGINSET @strSimpleFilter = ''SET @strFilter = ''ENDIF @Group IS NOT NULL AND @Group != ''SET @strGroup = ' GROUP BY ' + @Group + ' 'ELSESET @strGroup = ''set @strtemp= ' SELECT @Counts = count('+@PrimaryKey+') FROM ' ++ @Tables + @strFilter + ' ' + @strGroup +' '--exec (@strtemp)exec sp_executesql @strtemp,N'@Counts int out ',@Counts outset @RecordCount=@Countsset @pageCount=(@Counts+@pageSize-1)/@pageSize /**//**当前页大于总页数 取最后一页**/ if @CurrentPage>@pageCount set @CurrentPage=@pageCount/*默认当前页*/IF @CurrentPage < 1SET @CurrentPage = 1/*设置分页参数.*/SET @strPageSize = CAST(@PageSize AS varchar(50))SET @strStartRow = CAST(((@CurrentPage - 1)*@PageSize + 1) AS varchar(50))/*执行查询语句*/ EXEC('DECLARE @SortColumn ' + @type + 'SET ROWCOUNT ' + @strStartRow + 'SELECT @SortColumn=' + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + 'SET ROWCOUNT ' + @strPageSize + 'SELECT ' + @Fields + ' FROM ' + @Tables + ' WHERE ' + @strSortColumn + @operator + ' @SortColumn ' + @strSimpleFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '')return @pageCountGO 尽量不要用 in, or, *,等等最好每个查询都有where exec sp_executesql @strtemp,N'@Counts int out ',@Counts out不要每次都count(),会很好性能的,可以作输入输出参数,避免每次都count(),性能会有很大提高。 count()作为自带函数 性能应该还好吧在这里不这么用 还有其他方法吗? count()可以作为output参数,CREATE PROCEDURE fenye(@RecordCount int =0 output,@Tables varchar(1000),@PrimaryKey varchar(100),@Sort varchar(200) = NULL,@CurrentPage int = 1,@PageSize int = 10,@Fields varchar(1000) = '*',@Filter varchar(1000) = NULL,@Group varchar(1000) = NULL,@Totalcount int = 0 output -- 加这个参数,如果totalcount<=0 就count(),否则不count(),这样会好很多,每次count()会耗很多资源。 set @strtemp= ' SELECT @Counts = count('+@PrimaryKey+') FROM ' ++ @Tables + @strFilter + ' ' + @strGroup +' '这句话对么?怎么++都出来了? count() 在我的需求中是必须的我需要算出每次查询的结果数目 并根据这个进行分页的硬件方面我不大了解 好像是自强3.0CPU 双核的 2G内存 看看执行计划,那部分最消耗CPU资源,先针对这部分进行优化,至于怎么优化,要具体问题具体分析了,没有统一的标准的 我同意“wangtiecheng(不知不为过,不学就是错!) ”的说法跟踪方法:开始->所有程序->Microsoft SQL Server->事件探查器->文件->新建->跟踪->输入密码->确定->运行然后你观察“CPU”列里,里面的单位是毫秒,是哪个查询消耗的时间最多你就编辑这个查询。有的时候1个效率很低但执行频率又很高的查询会让你的数据库服务器CPU始终维持在较高的水平。 直接把最终执行的SQL语句拿出来分析(可以在 /*执行查询语句*/ 之前加上Print)可能最终问题还是在SELECT语句或者索引上 赞同,可是这些lz都用到了.Fields 这个就是* SQL2005在万网不知道如何导入数据,请帮忙,谢谢! 如何填充下列数据 sqlserver 表数量有极限么 被字符阁开的数据查询,1|2,查询到两列1,2 SQL2005事务处理的基础问题 行列转求解 sql server连不上有图 导入.sql文件到数据库问题。急!!!!在线等待!!!实现马上结帐! 奇怪的"E-mail”是SQl 的保留字吗?? 这个标题我不知道该怎么写..... 2005导入数据如果出错,得从头导入,有什么办法可以解决不从头导入呢? 加了一台服务器放WEB,原服务器只放数据库怎么还是CPU占得老高,内存占得老多
不过查询速度挺快的 近200万的数据 每页显示20条 基本上都在1秒以下
并且我也没找到更好的 优化方法 现在不存储过程贴出来 希望高人能帮我分析优化下
CREATE PROCEDURE fenye
(@RecordCount int =0 output,
@Tables varchar(1000),
@PrimaryKey varchar(100),
@Sort varchar(200) = NULL,
@CurrentPage int = 1,
@PageSize int = 10,
@Fields varchar(1000) = '*',
@Filter varchar(1000) = NULL,
@Group varchar(1000) = NULL)
AS
/*默认排序*/
DECLARE @Counts int
DECLARE @pageCount int
IF @Sort IS NULL OR @Sort = ''
SET @Sort = @PrimaryKeyDECLARE @SortTable varchar(100)
DECLARE @SortName varchar(100)
DECLARE @strSortColumn varchar(200)
DECLARE @operator char(2)
DECLARE @type varchar(100)
DECLARE @prec int
DECLARE @strtemp nvarchar(1000)
/*设定排序语句.*/
IF CHARINDEX('DESC',@Sort)>0
BEGIN
SET @strSortColumn = REPLACE(@Sort, 'DESC', '')
SET @operator = '<='
END
ELSE
BEGIN
IF CHARINDEX('ASC', @Sort) = 0
SET @strSortColumn = REPLACE(@Sort, 'ASC', '')
SET @operator = '>='
ENDIF CHARINDEX('.', @strSortColumn) > 0
BEGIN
SET @SortTable = SUBSTRING(@strSortColumn, 0, CHARINDEX('.',@strSortColumn))
SET @SortName = SUBSTRING(@strSortColumn, CHARINDEX('.',@strSortColumn) + 1, LEN(@strSortColumn))
END
ELSE
BEGIN
SET @SortTable = @Tables
SET @SortName = @strSortColumn
END
/*设定排序字段类型.*/
SELECT @type=t.name, @prec=c.prec
FROM sysobjects o
JOIN syscolumns c on o.id=c.id
JOIN systypes t on c.xusertype=t.xusertype
WHERE o.name = @SortTable AND c.name = @SortNameIF CHARINDEX('char', @type) > 0
SET @type = @type + '(' + CAST(@prec AS varchar) + ')'DECLARE @strPageSize varchar(50)
DECLARE @strStartRow varchar(50)
DECLARE @strFilter varchar(1000)
DECLARE @strSimpleFilter varchar(1000)
DECLARE @strGroup varchar(1000)/*筛选以及分组语句.*/
IF @Filter IS NOT NULL AND @Filter != ''
BEGIN
SET @strFilter = ' WHERE ' + @Filter + ' '
SET @strSimpleFilter = ' AND ' + @Filter + ' '
END
ELSE
BEGIN
SET @strSimpleFilter = ''
SET @strFilter = ''
ENDIF @Group IS NOT NULL AND @Group != ''
SET @strGroup = ' GROUP BY ' + @Group + ' '
ELSE
SET @strGroup = ''set @strtemp= ' SELECT @Counts = count('+@PrimaryKey+') FROM ' ++ @Tables + @strFilter + ' ' + @strGroup +' '
--exec (@strtemp)
exec sp_executesql @strtemp,N'@Counts int out ',@Counts out
set @RecordCount=@Counts
set @pageCount=(@Counts+@pageSize-1)/@pageSize /**//**当前页大于总页数 取最后一页**/
if @CurrentPage>@pageCount
set @CurrentPage=@pageCount
/*默认当前页*/
IF @CurrentPage < 1
SET @CurrentPage = 1/*设置分页参数.*/
SET @strPageSize = CAST(@PageSize AS varchar(50))
SET @strStartRow = CAST(((@CurrentPage - 1)*@PageSize + 1) AS varchar(50))
/*执行查询语句*/
EXEC(
'
DECLARE @SortColumn ' + @type + '
SET ROWCOUNT ' + @strStartRow + '
SELECT @SortColumn=' + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '
SET ROWCOUNT ' + @strPageSize + '
SELECT ' + @Fields + ' FROM ' + @Tables + ' WHERE ' + @strSortColumn + @operator + ' @SortColumn ' + @strSimpleFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '
'
)
return @pageCount
GO
最好每个查询都有where
不要每次都count(),会很好性能的,可以作输入输出参数,避免每次都count(),性能会有很大提高。
CREATE PROCEDURE fenye
(@RecordCount int =0 output,
@Tables varchar(1000),
@PrimaryKey varchar(100),
@Sort varchar(200) = NULL,
@CurrentPage int = 1,
@PageSize int = 10,
@Fields varchar(1000) = '*',
@Filter varchar(1000) = NULL,
@Group varchar(1000) = NULL,
@Totalcount int = 0 output -- 加这个参数,如果totalcount<=0 就count(),否则不count(),这样会好很多,每次count()会耗很多资源。
我需要算出每次查询的结果数目 并根据这个进行分页的硬件方面我不大了解 好像是自强3.0CPU 双核的 2G内存
跟踪方法:
开始->所有程序->Microsoft SQL Server->事件探查器->文件->新建->跟踪->输入密码->确定->运行
然后你观察“CPU”列里,里面的单位是毫秒,是哪个查询消耗的时间最多你就编辑这个查询。
有的时候1个效率很低但执行频率又很高的查询会让你的数据库服务器CPU始终维持在较高的水平。
可能最终问题还是在SELECT语句或者索引上
Fields 这个就是*