我有一个存储过程,可以搜索组合表中的多个列。
但是,它可以在15秒内搜索该组合表中的值。该表需要9秒才能加载,所以我不确定,也许是因为我的表太大了?
所以我只是想知道是否有办法让这个查询运行得更快。
这是我的存储过程:
create procedure LRMWEB_Search
@input nvarchar(1500)
AS
SET NOCOUNT ON;
SELECT tr.ResourceID ,
tr.ProjectFile,
tr.ResourceFile,
tr.ResourceName,
trt.Culture,
trt.TranslatedFlag,
trt.TranslatedValue,
tr.Comments,
tr.IsApproved
FROM tblResourcesTranslated_NEW trt
INNER JOIN tblResources_NEW tr ON trt.ResourceID = tr.ResourceID
where tr.ResourceID like '%'+ @input + '%'
OR tr.ProjectFile like '%'+ @input + '%'
OR tr.ResourceFile like '%'+ @input + '%'
OR tr.ResourceName like '%'+ @input + '%'
OR tr.ResourceValue like '%'+ @input + '%'
OR tr.Comments like '%'+ @input + '%'
OR trt.Uid like '%'+ @input + '%'
OR trt.TranslatedValue like '%'+ @input + '%'
;
答案 0 :(得分:2)
like
的任何使用都会排除索引,除非它具有带通配符后缀的固定前缀,例如where foo like 'bar%'
。您的like
表达式(例如'%xxx%'
)不符合该要求。
因此,虽然连接条件可能具有覆盖索引,但其他方法都没有,因此需要对连接表进行表扫描。
简而言之,没有办法在
之外修复性能答案 1 :(得分:0)
SELECT tblResources_NEW.ResourceID
,tblResources_NEW.ProjectFile
,tblResources_NEW.ResourceFile
,tblResources_NEW.ResourceName
,tblResourcesTranslated_NEW.Culture
,tblResourcesTranslated_NEW.TranslatedFlag
,tblResourcesTranslated_NEW.TranslatedValue
,tblResources_NEW.Comments
,tblResources_NEW.IsApproved
FROM
(
SELECT
tblResources_NEW.ResourceID
,tblResources_NEW.ProjectFile
,tblResources_NEW.ResourceFile
,tblResources_NEW.ResourceName
,tblResources_NEW.Comments
,tblResources_NEW.IsApproved
FROM tblResources_NEW
WHERE
tblResources_NEW.ResourceID like '%'+ @input + '%'
OR tblResources_NEW.ProjectFile like '%'+ @input + '%'
OR tblResources_NEW.ResourceFile like '%'+ @input + '%'
OR tblResources_NEW.ResourceName like '%'+ @input + '%'
OR tblResources_NEW.ResourceValue like '%'+ @input + '%'
OR tblResources_NEW.Comments like '%'+ @input + '%'
) AS tblResources_NEW
INNER JOIN
(
SELECT
tblResourcesTranslated_NEW.ResourceID
,tblResourcesTranslated_NEW.Culture
,tblResourcesTranslated_NEW.TranslatedFlag
,tblResourcesTranslated_NEW.TranslatedValue
FROM tblResourcesTranslated_NEW
WHERE
tblResourcesTranslated_NEW.Uid like '%'+ @input + '%'
OR tblResourcesTranslated_NEW.TranslatedValue like '%'+ @input + '%'
) AS tblResourcesTranslated_NEW ON tblResourcesTranslated_NEW.ResourceID=tblResources_NEW.ResourceID
答案 2 :(得分:0)
如果你坚持为所有字段输入一个输入,我至少会通过动态SQL来提高性能。
Alter PROCEDURE LRMWEB_Search
(
@input nvarchar(1500)
)
AS
declare @sql varchar(2000);
SET NOCOUNT ON;
set @sql = 'SELECT
tblResources_NEW.ResourceID,
tblResources_NEW.ProjectFile,
tblResources_NEW.ResourceFile,
tblResources_NEW.ResourceName,
tblResourcesTranslated_NEW.Culture,
tblResourcesTranslated_NEW.TranslatedFlag,
tblResourcesTranslated_NEW.TranslatedValue,
tblResources_NEW.Comments,
tblResources_NEW.IsApproved
FROM
tblResourcesTranslated_NEW INNER JOIN
tblResources_NEW ON tblResourcesTranslated_NEW.ResourceID=tblResources_NEW.ResourceID
where ';
-- here I would concatenate all your string conditions
if (ISNUMERIC(@input)= 0)
Begin
. . . . . . .
End
-- here I would concatenate all your numeric conditions
if (ISNUMERIC(@input)= 1)
Begin
set @sql = @sql + ' OR tblResources_NEW.ResourceID like ''%@1%''';
. . . . .
End
-- call to execute
EXECUTE sp_executesql @sql, N'@1 varchar', @1 = @input;
这可以通过排除不需要的搜索来为您提供至少一些提升。但实际上,你应该通过对每个条件使用单个参数来做这样的事情。您可以将Null
中的那些从构建中排除到字符串中。
但是,再次,这个设计是BAD
。