高效运行大量动态SQL的方法

时间:2014-04-07 14:09:32

标签: sql sql-server tsql sql-server-2005 dynamic-sql

摘要

是否有一种有效的方法来运行大量的动态SQL(在SQL Server 2005上)?

详情

我们的系统允许用户创建“电子邮件提醒”订阅 - 系统上的新匹配每天通过电子邮件发送给他们。

订阅允许多种选项,包括使用搜索关键字。我自己编写的解析器会输出相应的SQL代码,并考虑andor和方括号()解析器将不允许任何可用于SQL注入的内容。

例如,用户可能会将关键字输入为this (that or other),结果查询最终会大致为......

SELECT *
FROM [VW_EMAIL_ALERT]
WHERE ([SEARCH] LIKE '%this%' AND ([SEARCH] LIKE '%that%' OR [SEARCH] LIKE '%other%'))

每晚,所有订阅都会单独处理,因为每个订阅都可能是唯一的。结果是批处理必须在每个订阅上运行游标并通过sp_executesql运行SQL。

显然这是非常低效的,并且可能导致严重的超载 - 在某些情况下导致超时。运行此处理的存储过程被编码为将订阅拆分为块,因此不会立即调用它们。

有更好/更有效的方法吗?

注意:遗憾的是,我们目前仍然支持最少的SQL Server 2005,因为我们的一些客户仍然使用该技术

2 个答案:

答案 0 :(得分:1)

如果您正在寻找效率最低的关键字,那么您可以这样做 类似'%任何东西不使用索引

使用FullText搜索索引单词

或者编写自己的解析器来索引唯一的单词
你会建立一个关键词表
并索引关键字
这是一个非常有效的查询

select id 
  from keywords 
 where keyword = 'this' 
intersect 
select id 
  from keywords 
 where keyword in ( 'that','other')

即使在关键字中使用通配符,它​​仍然比搜索整个文本更有效

答案 1 :(得分:0)

我希望这会有所帮助。在我的工作中,我们用这种实现替换了光标。

DECLARE
    @strSQL NVARCHAR(MAX) = ''

CREATE TABLE #tmp
(
    Result_Query VARCHAR(MAX)
)

INSERT INTO
    #tmp
SELECT
    'SELECT * FROM [VW_EMAIL_ALERT] WHERE ([SEARCH] = ''%this%'' AND ([SEARCH] = ''%that%'' OR [SEARCH] = ''%other%''))'

UNION

SELECT
    'SELECT * FROM [VW_EMAIL_ALERT] WHERE ([SEARCH] = ''%this1%'' AND ([SEARCH] = ''%that1%'' OR [SEARCH] = ''%other1%''))'

SELECT
    @strSQL = @strSQL + Result_Query + ';'
FROM
    #tmp

SET
    @strSQL = LEFT(@strSQL, LEN(@strSQL) - 1)

PRINT @strSQL
EXEC(@strSQL)