包含特定字符的记录列表的最佳SQL查询?

时间:2011-06-29 10:44:20

标签: sql sql-server tsql sql-server-2000

目前我正在使用相对较大的SQL Server 2000数据库。它的大小为80 GB,拥有数百万条记录。

我目前需要返回一个包含至少一系列非法字符的名称列表。非法字符只是指由客户定义的任意字符列表。在下面的例子中,我使用问号,分号,句号和逗号作为非法字符列表。

我最初想要做一个与正则表达式一起使用的CLR函数,但是因为它是SQL server 2000,我猜这是不可能的。

目前我这样做了:

select x from users
where 
columnToBeSearched like '%?%' OR
columnToBeSearched like '%;%' OR
columnToBeSearched like '%.%' OR
columnToBeSearched like '%,%' OR
otherColumnToBeSearched like '%?%' OR
otherColumnToBeSearched like '%;%' OR
otherColumnToBeSearched like '%.%' OR
otherColumnToBeSearched like '%,%'

现在,我不是一个SQL专家,但我觉得上面的查询效率很低。在具有数百万条记录的表中进行8次多通配符搜索,似乎可能会严重降低系统速度。虽然它似乎在测试服务器上运行良好,但我得到了“这必须完全错误”的氛围。

由于我最终需要在实时生产服务器上执行此脚本,我希望能够获得良好的性能,以免堵塞系统。可能需要稍后扩展该脚本以包含更多非法字符,但这不太可能。

总结一下:我的目标是获取一个记录列表,其中两列中的任何一列都包含客户定义的“非法字符”。数据库是实时且庞大的,所以我想要一种有效的方法,因为我相信上面的查询会非常慢。

有人能告诉我实现结果的最佳方法吗?谢谢!

/的Morten

4 个答案:

答案 0 :(得分:6)

它没有得到太多使用,但是LIKE语句接受了与Regex类似(但非常简化)的模式。 This link是它的msdn页面。

在您的情况下,您可以简化为(未经测试):

select x from users
where 
    columnToBeSearched like '%[?;.,]%' OR
    otherColumnToBeSearched like '%[?;.,]%'

另请注意,您可以将LIKE模式创建为变量,从而允许客户定义的部分要求。

另一个主要优化:如果您在用户行上有更新的日期(或时间戳)(对于任何审计历史记录类型的事物),那么您始终可以只查询自上次检查后更新的行。

答案 1 :(得分:3)

如果这是一个将重复运行的查询,那么最好为它创建一个索引。语法目前让我失望了,但你可以创建一个计算列(编辑:可能是PERSISTED计算列),如果columnToBeSearchedotherColumnToBeSearched包含非法字符,则为1,0除此以外。在该列上创建一个索引,只需选择列为1的所有行。这假定该数据库安装的非法字符集是固定的(我假设这是“客户指定的”)。另一方面,如果每个查询可能指定了一组不同的非法字符,则无效。

顺便说一下,如果您不介意读取未提交行的风险,可以在隔离级别为READ UNCOMMITTED的事务中运行查询,这样您就不会阻止其他事务。 / p>

答案 2 :(得分:0)

您可以尝试水平分区数据,并在一些较小的查询中“分割”您的查询。例如,你可以做

SELECT x FROM users 
WHERE users.ID BETWEEN 1 AND 5000 
AND -- your filters on columnToBeSearched

将结果重新放在一个列表中可能会有点不方便,但如果它是一个报告,你只提取一次(或偶尔提取一次),这可能是可行的。 我假设ID是用户的主键或具有索引定义的列,这意味着SQL应该能够创建一个有效的执行计划,它在尝试检查之前评估users.ID BETWEEN 1和5000(快)过滤器(可能很慢)。

答案 3 :(得分:0)

查找PATINDEX,它允许您输入一个字符数组PATINDEX('[._]',ColumnName)返回0或某个值中找到的非法字符的第一次出现的值。希望这会有所帮助。