如何更有效地搜索多列程序?

时间:2014-06-26 18:36:04

标签: sql sql-server performance

我有一个存储过程,可以搜索组合表中的多个列。

但是,它可以在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 + '%'
  ;

3 个答案:

答案 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