首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何提高T-SQL查询的速度

如何提高T-SQL查询的速度
EN

Stack Overflow用户
提问于 2009-08-10 11:37:15
回答 5查看 3.2K关注 0票数 1

我已经开发了几个T-SQL存储过程,它们可以迭代大量数据。第一个需要几分钟来运行一年的数据,这对我的目的来说已经很好了。第二个,使用相同的结构/算法,尽管需要更多的数据,需要两个小时,这是无法忍受的。

我使用SQL-Server和Query-Analyzer。是否有分析工具,如果有,它们是如何工作的?

或者,基于下面的伪代码,有没有关于如何提高速度的想法?简而言之,我使用游标遍历直接SELECT (来自几个连接表)中的数据。然后,我根据这些值构建一条INSERT语句,并将结果插入到另一个表中。在INSERTion之前,需要对一些SELECTed变量进行一些操作。这包括从日期值中提取一些日期部分,一些基本的浮点操作和一些字符串连接。

-粗略算法/伪代码

代码语言:javascript
复制
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
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-08-10 11:40:50

要做的第一件事-去掉光标...

代码语言:javascript
复制
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。

票数 11
EN

Stack Overflow用户

发布于 2009-08-10 11:41:49

丢掉光标。现在。(原因请看这里:Why is it considered bad practice to use cursors in SQL Server?)。

毫不粗鲁地说,您似乎是在采用过程化程序员的SQL方法,这种方法几乎总是次优的。

如果你正在做的事情很复杂,而且你没有信心,我会分三个步骤来做:

1)使用insert或Select into将核心数据选择到临时表中。

2)使用update进行操作-您可以只更新现有的列,或者在创建临时表时可能需要以正确的格式添加一些额外的列。如果需要,您可以使用多个update语句进一步分解它。

3)将其选择到您想要的任何位置。

如果您希望将其作为一个步骤调用,则可以将整个过程包装到一个存储过程中。

这使得调试变得很容易,如果其他人需要,也可以很容易地与他们一起工作。你可以将你的更新分解成单独的步骤,这样你就可以快速识别出哪里出了问题。

也就是说,从外观上看,我不认为您正在做的事情不能在一条insert语句中完成。这可能并不吸引人,但我相信它是可以做到的:

代码语言:javascript
复制
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)一些语言很难处理未命名的列(并且以一种非常不明确的方式处理它)。

票数 5
EN

Stack Overflow用户

发布于 2009-08-10 12:44:33

去掉游标和动态sql:

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1254408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档