我开发了几个T-SQL存储过程,它们迭代了相当多的数据。第一个需要花费几分钟来运行一年的数据,这对我的目的来说很好。第二个使用相同的结构/算法,虽然数据量更多,需要两个小时,这是无法忍受的。
我正在使用SQL-Server和Query-Analyzer。是否有任何分析工具,如果有,它们如何工作?
或者,根据下面的伪代码,有关如何提高速度的任何想法?简而言之,我使用游标迭代来自直接SELECT(来自几个连接表)的数据。然后我根据值构建一个INSERT语句,并将结果INSERT到另一个表中。一些SELECTed变量在INSERTion之前需要一些操作。包括从日期值中提取一些日期部分,一些基本的浮点运算和一些字符串连接。
---粗略算法/伪代码
DECLARE <necessary variables>
DECLARE @cmd varchar(1000)
DECLARE @insert varchar(100) = 'INSERT INTO MyTable COL1, COL2, ... COLN, VALUES('
DECLARE MyCursor Cursor FOR
SELECT <columns> FROM TABLE_1 t1
INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @VAL1, @VAL2, ..., @VALn
WHILE @@FETCH_STATUS = 0
BEGIN
@F = @VAL2 / 1.1 --- float op
@S = @VAL3 + ' ' + @VAL1
SET @cmd = @insert
SET @cmd = @cmd + DATEPART(@VAL1) + ', '
SET @cmd = @cmd + STR(@F) + ', '
SET @cmd = @cmd + @S + ', '
SET @cmd = @cmd + ')'
EXEC (@cmd)
FETCH NEXT FROM MyCursor @VAL1, @VAL2, ..., @VALn
END
CLOSE MyCursor
DEALLOCATE MyCursor
答案 0 :(得分:11)
要做的第一件事 - 摆脱光标......
INSERT INTO MyTable COL1, COL2, ... , COLN
SELECT ...cols and manipulations...
FROM TABLE_1 t1
INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey
大多数事情都应该直接用于TSQL(没有示例很难确定) - 你可以考虑使用UDF进行更复杂的操作。
答案 1 :(得分:5)
丢失光标。现在。 (请参阅此处了解原因:Why is it considered bad practice to use cursors in SQL Server?)。
没有粗鲁,你似乎采用程序员程序员的SQL方法,这几乎总是不太理想。
如果您正在做的事情很复杂而且您不自信我会分三步完成:
1)使用insert或select into将核心数据选择到临时表中。
2)使用update进行操作 - 您可以只更新现有列,或者在创建临时表时可能需要以正确的格式添加一些额外的列。如果需要,可以使用多个更新语句进一步细分。
3)将其选择到任何你想要的地方。
如果您想将其全部调用为一步,那么您可以将整个内容包装到存储过程中。
这使得调试变得容易,并且如果需要,可以让其他人轻松使用。您可以将更新分解为单个步骤,以便快速确定哪里出错。
那就是说我不相信你所做的事情不能从单一的插入声明中完成。它可能没有吸引力,但我相信它可以做到:
INSERT INTO NewTable
DATEPART(@VAL1) DateCol,
@STR(@VAL2 / 1.1) FloatCol,
@VAL3 + ' ' + @VAL1 ConcatCol
FROM TABLE_1 t1
INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey
DateCol,FloatCol和ConcatCol是您希望列具有的任何名称。虽然它们不是必需的,但最好将它们分配为(a)它使你更清楚你正在做什么和(b)某些语言与未命名的列斗争(并以非常不明确的方式处理它)。
答案 2 :(得分:0)
摆脱游标和动态sql:
INSERT INTO MyTable
(COL1, COL2, ... COLN)
SELECT
<columns>
,DATEPART(@VAL1) AS DateCol
,@STR(@VAL2 / 1.1) AS FloatCol
,@VAL3 + ' ' + @VAL1 AS ConcatCol
FROM TABLE_1 t1
INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey
答案 3 :(得分:0)
是否有任何分析工具,如果 那么,他们是如何运作的?
要回答有关查询调优工具的问题,可以使用TOAD for SQL Server来协助查询调优。
我非常喜欢这个工具,因为它将以20种不同的方式运行您的SQL语句,并比较执行计划以确定最佳方法。有时我会惊讶于它如何优化我的陈述,而且效果很好。
更重要的是,我使用它来成为一个更好的t-sql编写器,因为我使用了我编写的未来脚本的提示。我不知道TOAD如何使用这个脚本,因为正如其他人提到它使用光标,我不使用它们所以从来没有试过优化它。
TOAD是SQL Server功能的巨大工具箱,查询优化只是其中的一小部分。顺便说一下,我不以任何方式与Quest Software有任何关系。
答案 4 :(得分:0)
SQl Server还附带了一个名为SQL Server Profiler的分析工具。这是SSMS中Tools下菜单上的第一个选择。