如何使用游标优化此查询?

woo*_*ddy 0 sql t-sql sql-server optimization stored-procedures

DECLARE tableList CURSOR FOR    
    SELECT  t.name 
    FROM sys.tables t
        INNER JOIN sys.columns c
        ON t.object_id = c.object_id
    WHERE
            t.name NOT LIKE 'z%'
        AND t.name NOT LIKE '%delete%'
        AND t.name <> 'tblUsers'
        AND t.name <> 'tblUserLogins'
        AND t.name <> 'searchR'
        AND t.name <> 'tblUserPortfolio'
        AND t.name <> 'alerts_User'
        AND c.name LIKE 'userid'
        OR  c.name LIKE 'user_id'
    ORDER BY name
OPEN tableList
FETCH NEXT FROM tableList
INTO @tablename
Run Code Online (Sandbox Code Playgroud)

以上是建立游标的查询,并且它使用了不少LIKE,NOT LIKE操作,我认为可能是运行昂贵.

所以我问是否有更好的方法来构建查询而不使用太多LIKE/NOT LIKE并使其更优化.

谢谢.

编辑:

这里使用游标的意图是Loop Through所有匹配的表,因此我们可以动态插入/更新/删除记录.

我正在使用的数据库中有超过150个表,所以我认为sql server也可以做脏工作.

Ada*_*Dev 5

我会:

1)通过使用NOT IN而不是多个"...和t.name <> ..."使SQL更易读(IMO)
2)将c.name LIKE更改为单个IN子句,因为您似乎想要一个精确的匹配,不需要像

SELECT  t.name 
FROM sys.tables t
    INNER JOIN sys.columns c ON t.object_id = c.object_id
WHERE t.name NOT LIKE 'z%' AND t.name NOT LIKE  '%delete%' 
    AND t.name NOT IN  ('tblUsers','tblUserLogins','searchR','tblUserPortfolio','alerts_User')
    AND c.name IN ('userid','user_id') 
ORDER BY name
Run Code Online (Sandbox Code Playgroud)

这实际上不太可能在性能方面做出很多不同,但我认为它使其更具可读性/可维护性.

但是,我要提出的主要观点是你是否真的需要一个光标 - 我绝对希望删除它,而采用基于集合的方法.虽然需要知道你在光标中做了什么,以便提出一个替代方案.

编辑: 您可以尝试这种动态生成SQL并一次执行它的方法(简单示例,假设您希望将相同的行插入到每个具有相同结构的表中).很难知道这是否真的适合你的确切场景(或者它是否真的会产生有价值的差异),但知道这种技术会很有用.

DECLARE @nSQL NVARCHAR(MAX)
SELECT @nSQL = COALESCE(@nSQL, '')  + 
'INSERT ' + QUOTENAME(t.name) + '([SomeCol]) VALUES (@ValueToInsert);' + CHAR(10)
FROM sys.tables t
    INNER JOIN sys.columns c ON....
...{rest of current SELECT)

-- comment out PRINT, and uncomment EXECUTE statement to actually run the SQL
PRINT @nSQL
-- EXECUTE sp_executesql @nSQL, N'@ValueToInsert VARCHAR(10)', 'NewValue'
Run Code Online (Sandbox Code Playgroud)