我是做ASP网站开发的数据库有一张表有近200万条数据我觉得最可能是查询这张表时出的问题我想知道数据库的cpu占用跟sql事件跟踪器里看到的cpu占用时间 、reads等有什么关系。这些数值在哪个范围内是允许的可接受的,如果超出了该怎么优化?我目前的优化工作主要做了 建了聚集索引,使用存储过程期待高手进来

解决方案 »

  1.   

    电脑应该没感染病毒 数据分离目前还没去考虑 因为是会员表 我想200W也不是很多吧索引我已经在使用了能解答下我下面的问题吗我想知道数据库的cpu占用跟sql事件跟踪器里看到的cpu占用时间 、reads等有什么关系。这些数值在哪个范围内是允许的可接受的,如果超出了该怎么优化?
      

  2.   

    如果排除了以上因素,跟踪一下是什么SQL查询时导致CPU占用100%很有可能是效率极低的SQL查询时导致的比如:是否有cross join 类型的查询
      

  3.   

    有个分页存储过程 一运行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 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
      

  4.   

    尽量不要用 in, or, *,等等
    最好每个查询都有where
      

  5.   

    exec sp_executesql @strtemp,N'@Counts int out ',@Counts out
    不要每次都count(),会很好性能的,可以作输入输出参数,避免每次都count(),性能会有很大提高。
      

  6.   

    count()作为自带函数 性能应该还好吧在这里不这么用 还有其他方法吗?
      

  7.   

    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()会耗很多资源。
      

  8.   

    set @strtemp= ' SELECT @Counts = count('+@PrimaryKey+')  FROM ' ++ @Tables + @strFilter + ' ' + @strGroup +' '这句话对么?怎么++都出来了?
      

  9.   

    count() 在我的需求中是必须的
    我需要算出每次查询的结果数目 并根据这个进行分页的硬件方面我不大了解 好像是自强3.0CPU 双核的 2G内存
      

  10.   

    看看执行计划,那部分最消耗CPU资源,先针对这部分进行优化,至于怎么优化,要具体问题具体分析了,没有统一的标准的
      

  11.   

    我同意“wangtiecheng(不知不为过,不学就是错!) ”的说法
    跟踪方法:
    开始->所有程序->Microsoft SQL Server->事件探查器->文件->新建->跟踪->输入密码->确定->运行
    然后你观察“CPU”列里,里面的单位是毫秒,是哪个查询消耗的时间最多你就编辑这个查询。
    有的时候1个效率很低但执行频率又很高的查询会让你的数据库服务器CPU始终维持在较高的水平。
      

  12.   

    直接把最终执行的SQL语句拿出来分析(可以在 /*执行查询语句*/  之前加上Print)
    可能最终问题还是在SELECT语句或者索引上
      

  13.   

    赞同,可是这些lz都用到了.
    Fields 这个就是*