本帖最后由 snleo 于 2009-06-18 00:42:29 编辑

解决方案 »

  1.   

    你在语句里加入一些时间的,返回时间看一下哪里执行最花时间,然后再考虑那一段该怎么去改写SQL语句。我前段时间写段代码,数据库数据才二十几万行,从代码开始到结束竟然要花一秒钟以上,最慢的时候花了三秒多,我就在一些地方加了GetTickCount(Windows API)来取出时间,这才找出了哪里花的时间最长。然后再去修改。后来数据到六十几万行,从开始到结束最多200多毫秒,最快60多毫秒
      

  2.   

    dbo.TableView是自己做的一个View,含有tab_name AS t_name, [col_name] AS c_name, [type]三个字段。
    运行速度在3-4分钟,因为除了cursor其他办法不会用。
    IF OBJECT_ID('tempdb..#stats') IS NOT NULL 
    BEGIN
    DROP TABLE #stats
    END
    SELECT tab_name AS t_name, [col_name] AS c_name, [type] INTO #stats FROM dbo.TableView
    ALTER TABLE #stats ADD c_max NVARCHAR(50), c_min NVARCHAR(50), c_countrows INT, c_countvalid INT
    GODECLARE
    @t_name nvarchar(50),
    @c_name nvarchar(50),
    @c_type nvarchar(50),
    @c_max nvarchar(50),
    @c_min nvarchar(50),
    @c_countrows int,
    @c_countvalid int
    DECLARE c_cursor CURSOR FOR
    SELECT * FROM #stats
    OPEN c_cursor
    FETCH NEXT FROM c_cursor INTO
    @t_name, @c_name, @c_type, @c_max, @c_min, @c_countrows, @c_countvalid
    WHILE @@FETCH_STATUS = 0
    BEGIN
    IF @c_type='datetime' OR @c_type='int' OR @c_type='decimal' OR @c_type='float' OR @c_type='real'
    BEGIN
    PRINT ('UPDATE #stats SET c_max=(SELECT MAX(' + @c_name + ') FROM ' + @t_name + '),c_min=(SELECT MIN(' + @c_name + ') FROM ' + @t_name + '),c_countrows=(SELECT COUNT(*) FROM' + @t_name + '),c_countvalid=(SELECT COUNT(' + @c_name + ') FROM ' + @t_name + ') WHERE t_name=''' + @t_name + ''' AND c_name=''' + @c_name + '''')
        END
        EXEC ('UPDATE #stats SET c_countrows=(SELECT COUNT(*) FROM ' + @t_name + '),c_countvalid=(SELECT COUNT(' + @c_name + ') FROM ' + @t_name + ') WHERE t_name=''' + @t_name + ''' AND c_name=''' + @c_name + '''')
        FETCH NEXT FROM c_cursor INTO
        @t_name, @c_name, @c_type, @c_max, @c_min, @c_countrows, @c_countvalid
    END
    CLOSE c_cursor
    DEALLOCATE c_cursor
    GO
    ALTER TABLE #stats ADD c_completeness FLOAT
    GO
    UPDATE #stats SET c_completeness=CONVERT(FLOAT,ISNULL(c_countvalid,0))/(CASE WHEN CONVERT(FLOAT,ISNULL(c_countrows,0))=0 THEN -1 ELSE CONVERT(FLOAT,ISNULL(c_countrows,0)) END)
    GO
    SELECT * FROM #stats ORDER BY t_name, c_name
    DROP TABLE #stats
    GO