2013-02-27 28 views
1

我传递一个逗号分隔的,我需要比较数据库优化与多个存储过程“LIKE” S

这里的值的列表是我传递中的值的例子:

@orgList = "1123, 223%, 54%" 

要使用通配符,我认为我必须做LIKE,但查询运行很长时间,只返回14行(结果是正确的,但它只是永远存在,可能是因为我错误地使用了连接)

我可以做得更好吗?

这就是我现在做的事:

​​

最终的结果将是所有行maintable.org为1123,或223开头或以554

的原因开始为我的约会疯狂的因为有时存储过程只会检查一年,有时是一年的范围,有时是为特定的日期,有时是为日期范围检查......没有使用的所有内容都以空值传递。

也许问题出在那里?

+0

maintainble.org的数据类型是什么? – 2013-02-27 13:55:35

+0

它是一个varchar(10) – 2013-02-27 13:56:28

+2

我假设你正在使用MS SQL Server?如果是,编辑并添加标签,选择正确的版本。这样问题就会更加明显。 – Yaroslav 2013-02-27 13:59:01

回答

1

尝试这样:

Declare @tempTable Table 
(
    -- Since the column is a varchar(10), you don't want to use nvarchar here. 
    SearchOrg varchar(20) 
); 

INSERT INTO @tempTable 
SELECT * FROM dbo.udf_split(@orgList); 

SELECT 
    something 
FROM 
    maintable gt 
WHERE 
    some where statements go here 
And 
    Exists 
    (
     SELECT 1 
     FROM @tempTable tt 
     WHERE gt.org Like tt.SearchOrg 
    ) 
+0

为什么这会更快?这不是批评的方式,我只是好奇:) – RobJohnson 2013-02-27 14:08:00

+0

@RobJohnson:两个原因。原始版本在表变量中使用了'nvarchar',这将强制SQL在加入之前将每行的'varchar'值转换为。如果临时表中有多个匹配项目,您将获得'maintable'行的多个副本。 – 2013-02-27 14:12:56

+0

@RichardDeeming - 我更新了where语句的查询,这可能是我执行时间的原因吗? – 2013-02-27 14:23:57

1

您的查询可能难以优化。部分问题是where条款中的内容。您可能首先要过滤这些内容,然后使用like进行加入。或者,您可以尝试加快连接速度,然后对结果执行全表扫描。

SQL Server应该优化like表单'abc%'的语句 - 也就是说,通配符在最后。 (例如,请参见here)。因此,您可以从maintable.org上的索引开始。幸运的是,你的例子符合这个标准。但是,如果您有'%abc' - 通配符优先 - 那么优化将不起作用。

要使指标最好地发挥作用,可能还需要考虑where条款中的条件。换句话说,添加索引是暗示性的,但查询的其余部分可能会阻止索引的使用。

而且,让我补充一点,这些类型搜索的最佳解决方案是在SQL Server中使用全文搜索功能(请参阅here)。

+0

我更新了我在哪里的声明,他们有点出现在外,如果您看到某些内容,请让我知道。 – 2013-02-27 14:24:27

+0

@TanyaXrum。 。 。这将是具有挑战性的,因为'where'陈述在两个领域有不平等。尝试在该领域的指数。如果它不起作用并且需要性能,则可能需要转到全文搜索功能。 – 2013-02-27 14:32:38

1

带有可选过滤器和由表(!)驱动的LIKE这样的动态查询很难优化,因为几乎没有任何内容是静态已知的。优化器必须创建一个非常通用的计划。

你可以做两件事情通过magnitute的订单加快这:

  1. 播放与OPTION (RECOMPILE)。如果编译times可以接受,这将至少处理所有可选的过滤器(但不包括LIKE表)。
  2. 做代码生成和EXEC sp_executesql的代码。使用内嵌到SQL中的所有LIKE子句构建查询,使其看起来像这样:WHERE a LIKE @like0 OR a LIKE @like1 ...(不确定是否需要ORAND)。这允许优化器摆脱连接并执行正常的谓词)。