我正在构建查询,最新一步涉及添加SELECT COUNT(*) FROM [modification]
子句以允许我检测查询的最后一行,但它会破坏性能:
SELECT CONCAT(
IIF(row_number() OVER (ORDER BY forecastId) % 50000 = 1,
CONCAT('INSERT INTO modification (userId, epochTime, ',
'forecastId, description, auxText, auxDate) VALUES ('),
' ('),
userId, ',',
epochTime, ',',
forecastId, ',',
'''', dbo.encode4MySql(description), ''',',
'''', dbo.encode4MySql(auxText), ''',',
'''', CONVERT(VARCHAR(20), auxDate, 120), ''')',
IIF(row_number() OVER (ORDER BY forecastId) % 50000 = 0
OR row_number() OVER (ORDER BY forecastId) =
(SELECT COUNT(*) FROM modification),
'; COMMIT;', ','))
FROM modification
ORDER BY forecastId;
如果您无法看到我正在做的事情,我一次只能构建50000行的INSERT () VALUES (),(),(),...
语句。
请限制针对评论的完全替代方法的建议。我正在寻找一种方法来找到最后一个行号而不会大幅减慢查询速度 - 它确实如此。
我并不熟悉查询计划,但如果有帮助,可以在此发帖。我在这里尝试过很多关于相关问题的事情,但是没有什么我可以开始工作的。
答案 0 :(得分:1)
您有一个相当复杂的表达式,因此SQL Server可能无法对其进行优化。将逻辑移动到FROM
子句:
FROM (SELECT m.*, COUNT(*) OVER () as num_rows
FROM modification m
) m
然后在查询的其余部分使用num_rows
。
答案 1 :(得分:1)
另一个选项是最终order by forecastId desc
中的or
:
IIF(row_number() OVER (ORDER BY forecastId) % 50000 = 0
OR row_number() OVER (ORDER BY forecastId desc) = 1,
'; COMMIT;', ','))
答案 2 :(得分:0)
假设您不想更改当前设计,可以在最后添加额外的UNION ALL步骤。通过查看您的查询,看起来更改查询的唯一目的是在最后添加COMMIT。
CURRENT QUERY
UNION ALL
SELECT 'COMMIT;';
请告诉我这是否适合您。
*********** UPDATE *********
我认为此查询更容易排除故障。看看它是否会更好。你必须为你的桌子插入CTE部分。
SELECT BusinessEntityID,JobTitle,HireDate INTO dbo.TestTable FROM [HumanResources].[Employee]
SELECT TOP 0 BusinessEntityID,JobTitle,HireDate INTO dbo.TestTable2 FROM [HumanResources].[Employee]
SET NOCOUNT ON
WITH CTE AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) Col,
' (' +
CAST(BusinessEntityID AS VARCHAR(20)) +
', ''' +
JobTitle +
''', ''' +
CONVERT(VARCHAR(20), HireDate, 120) +
''')' Query
FROM TestTable
)
SELECT
CASE
WHEN COL % 50 = 0 THEN ', ' + Query + ' COMMIT;'
WHEN COL % 50 = 1 THEN ' INSERT INTO dbo.TestTable2 (BusinessEntityID, JobTitle, HireDate) VALUES ' + Query
ELSE ', ' + Query
END
FROM CTE
UNION ALL SELECT 'COMMIT;'