How to optimize this query using cursor?
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'
精彩评论