Sql 为什么这个查询需要这么长时间,我如何提高它的性能?
总而言之,我有一个查询,它将N个相同的行插入到一个表中,唯一的区别是1列的值从0、1、…、N开始,如果已经有一列具有该值,我不会插入任何行。我的程序是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)
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