我传入了一个以逗号分隔的值列表,我需要与数据库进行比较
以下是我传递的值的示例:
@orgList = "1123, 223%, 54%"
要使用通配符我认为我必须做LIKE
但是查询运行很长时间并且只返回14行(结果是正确的,但它只是永远消失,可能是因为我正在使用连接不正确地)
我可以做得更好吗?
这就是我现在所做的:
declare @tempTable Table (SearchOrg nvarchar(max) )
insert into @tempTable
select * from dbo.udf_split(@orgList) as split
-- this splits the values at the comma and puts them in a temp table
-- then I do a join on the main table and the temp table to do a like on it....
-- but I think it's not right because it's too long.
select something
from maintable gt
join @tempTable tt on gt.org like tt.SearchOrg
where
AYEAR= ISNULL(@year, ayear)
and (AYEAR >= ISNULL(@yearR1, ayear) and ayear <= ISNULL(@yearr2, ayear))
and adate = ISNULL(@Date, adate)
and (adate >= ISNULL(@dateR1, adate) and adate <= ISNULL(@DateR2 , adate))
最终结果将是maintable.org
为1123,或以223开头或以554开头的所有行
我日期疯狂的原因是因为有时候存储过程只检查一年,有时是一年的范围,有时是特定日期,有时是日期范围......所有未使用的内容都是以null为单位
也许问题存在?
答案 0 :(得分: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
)
答案 1 :(得分:1)
您的查询可能难以优化。部分问题是where
条款中的内容。您可能希望先过滤这些,然后使用like
进行连接。或者,您可以尝试更快地进行连接,然后对结果进行全表扫描。
SQL Server应该优化形式为'abc%'的like
语句 - 也就是说,通配符在最后的位置。 (例如,请参阅here。)因此,您可以从maintable.org
上的索引开始。幸运的是,您的示例符合此标准。但是,如果您有'%abc' - 通配符首先出现 - 那么优化将无效。
为使索引最佳,可能还需要考虑where
子句中的条件。换句话说,添加索引是暗示性的,但查询的其余部分可能会排除使用索引。
而且,让我补充一点,这些类型的搜索的最佳解决方案是使用SQL Server中的全文搜索功能(请参阅here)。
答案 2 :(得分:1)
这种带有可选过滤器的动态查询和由表(!)驱动的LIKE
非常难以优化,因为几乎没有任何静态知识。优化器必须创建一个非常通用的计划。
你可以做两件事来加速大量订单:
OPTION (RECOMPILE)
进行游戏。如果编译times
是可接受的,那么至少会处理所有可选的过滤器(但不能处理LIKE表)。EXEC sp_executesql
代码。使用内联到SQL中的所有LIKE
子句构建一个查询,使其看起来像这样:WHERE a LIKE @like0 OR a LIKE @like1 ...
(不确定是否需要OR
或AND
)。这允许优化器摆脱连接并只执行正常的谓词。