开发者

How to optimize this query using cursor?

开发者 https://www.devze.com 2023-03-16 15:40 出处:网络
DECLARE tableList CURSOR FOR SELECTt.name FROM sys.tables t INNER JOIN sys.columns c ON t.object_id = c.object_id
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

Above is the query for building the cursor, and it is using quite a few LIKE, NOT LIKE operations,开发者_如何学JAVA which I assume might be expensive to run.

So I am asking if there is any better approach to build up a query without using too many LIKE/NOT LIKE and make it more optimal.

Thanks.

EDIT:

The intention of using cursor here is to Loop Through all matched tables so we then can insert/update/delete records dynamically.

There are more than 150 tables in the database that I am using, so I thought that sql server might as well do the dirty work.


I would:

1) make the SQL more readable (IMO) by using NOT IN instead of multiple "... and t.name <> ..."
2) changed c.name LIKEs to a single IN clause as you appear to want an exact match, not needing LIKE

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

This actually isn't likely to make a great deal of different tbh performance-wise, but I think makes it more readable/maintainable.

But, the main point I would raise is whether you actually need a cursor at all - I'd definitely look to remove that in favour of a set-based approach. Though would need to know what you are doing in the cursor in order to suggest an alternative.

Edit: You could try this kind of approach which dynamically generates the SQL and executes it in one go (simple example, assuming you want to insert the same row into each table which each has the same structure). Difficult to know if this would really suit your exact scenario (or whether it would actually make a worthwhile difference), but can be useful to know this technique.

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'
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号