为什么这个查询需要这么长时间,我如何才能提高它的性能?
Why does this query take so long, and how I can increase its performance?
我有一个查询,总而言之,将 N
相同的行插入到 table 中,唯一的区别是 1 列的值来自 0
、1
, ..., N
如果已经有一个具有该值的列,我不会插入 insert any 。我的程序是
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
当 boardPageCeiling
= 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
。
您可以使用合并语句改进该查询
插入以下 table:
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”替换为您自己
我有一个查询,总而言之,将 N
相同的行插入到 table 中,唯一的区别是 1 列的值来自 0
、1
, ..., N
如果已经有一个具有该值的列,我不会插入 insert any 。我的程序是
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
当 boardPageCeiling
= 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
。
您可以使用合并语句改进该查询
插入以下 table:
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”替换为您自己