Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么这个查询需要这么长时间,我如何提高它的性能?_Sql_Sql Server_Stored Procedures_Query Optimization_Database Performance - Fatal编程技术网

Sql 为什么这个查询需要这么长时间,我如何提高它的性能?

Sql 为什么这个查询需要这么长时间,我如何提高它的性能?,sql,sql-server,stored-procedures,query-optimization,database-performance,Sql,Sql Server,Stored Procedures,Query Optimization,Database Performance,总而言之,我有一个查询,它将N个相同的行插入到一个表中,唯一的区别是1列的值从0、1、…、N开始,如果已经有一列具有该值,我不会插入任何行。我的程序是 BEGIN DECLARE @i INT = 0; WHILE(@i <= @boardPageCeiling) BEGIN IF NOT EXISTS(SELECT 1 FROM PageArchives WHERE PageType = 'Board' AND PageNum = @i)

总而言之,我有一个查询,它将N个相同的行插入到一个表中,唯一的区别是1列的值从0、1、…、N开始,如果已经有一列具有该值,我不会插入任何行。我的程序是

BEGIN
    DECLARE @i INT = 0;
    WHILE(@i <= @boardPageCeiling)
    BEGIN
        IF NOT EXISTS(SELECT 1 FROM PageArchives WHERE PageType = 'Board' AND PageNum = @i)
        BEGIN
            INSERT INTO PageArchives
                (PageType, ThreadId, Html, PageNum, RetrievalAttempted, RetrievalSucceeded, RetrievalDate, RetrievalPriority, ProcessAttempted, ProcessingSucceeded, ProcessDate)
            VALUES
                ('Board', NULL, NULL, @i, 0, NULL, NULL, 0, 0, NULL, NULL)
        END
        SET @i = @i + 1;
    END
END

当BoardPage天花板=6000时,这需要20秒以上的时间来执行。考虑到复杂性,似乎非常长。

只需使用一个查询。唯一一个非常棘手的部分是生成一系列数字:

WITH digits(d) as (
      SELECT *
      FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) v(d)
     ),
     n(n) as (
      SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 as seqnum
      FROM d CROSS JOIN d CROSS JOIN d CROSS JOIN d
     )
INSERT INTO PageArchives (PageType, PageNum, RetrievalDate, RetrievalPriority, ProcessAttempted)
    SELECT 'Board', PageNum, 0, 0, 0
    FROM n
    WHERE n.n <= @boardPageCeiling AND
          NOT EXISTS (SELECT 1 FROM PageArchives pa WHERE pa.PageNum = n.n);

我从INSERT中删除了NULL值,因为默认情况下这些值可能被设置为NULL。

您可以使用merge语句来改进该查询。

插入下表:

WITH NumberTable  AS (
  SELECT 1 as Number
  UNION ALL
  SELECT Number+1
  FROM NumberTable  
  WHERE Number < 100 
)
SELECT 'Board', NULL, NULL, Number, 0, NULL, NULL, 0, 0, NULL, NULL FROM NumberTable  
where Number not in (SELECT PageNum FROM PageArchives WHERE PageType = 'Board')
OPTION (MAXRECURSION 0);

只是一个示例查询,用您自己替换100

请使用查询分析器检查您的查询,并使用调试点。变量@BoardPage天花板的数据类型是什么。请使用查询分析器。是否可以将其更改为实际基于集合的插入而不是迭代?创建一组要插入的必要数据,并以插入SELECT的形式实际执行这一操作,这非常简单。到目前为止,它正在使用该exists函数进行至少6K个查询。其他人提到了索引、分析器等,这会有所帮助,但相信通过对查询进行全面检查,您会看到更好的结果。您在PageType和PageNum上是否有索引?最终,最大递归次数超过了最大查询次数。。选项MAXRECURSION 0;它可以使递归级别超过100。还有其他问题吗?@user7127000。修复了语法。它可能会将WHERE NOT EXISTS与INSERT结合起来,但只要方法是逐行操作,它仍然会运行缓慢提示:googleforsqlrbar