如何优化一个相当直接的子查询,TOP会增加执行时间

时间:2013-02-23 00:25:05

标签: sql sql-server

我正在尝试为以下查询找到更好的解决方案,这需要几秒钟才能运行并添加TOP会增加执行时间。

SET STATISTICS TIME ON;
DECLARE @firstTerm NVARCHAR(255);
DECLARE @lastTerm NVARCHAR(255);
DECLARE @totalKeywords INT;
SET @firstTerm = 'john';
SET @lastTerm = 'doe';
SET @totalKeywords=2;

SELECT 20 AS [Priority], clientid AS ClientId
FROM clients.dbo.ViewClientsByFullname WITH (NOLOCK)
WHERE @totalKeywords > 1 AND fullname IN (
 SELECT COALESCE(ParentName + ' ','') + @lastTerm AS Name
 FROM dbo.DiminuitiveNames WITH (NOLOCK) 
 WHERE Name=@firstTerm OR ParentName=@firstTerm
 UNION
 SELECT COALESCE(Name + ' ','') + @lastTerm AS Name 
 FROM dbo.DiminuitiveNames WITH (NOLOCK) 
 WHERE ParentName IN (
  SELECT ParentName 
  FROM dbo.DiminuitiveNames WITH (NOLOCK) 
  WHERE Name=@firstTerm OR ParentName=@firstTerm
  )
 )

查询基本上是在检查表中是否有备用名称列表(例如@ firstTerm = Robert然后它还会获得bob,bobby,rob等列表),然后对这些备用名称进行搜索。 / p>

我试图用INNER JOIN想办法做到这一点,但暂时难倒。

2 个答案:

答案 0 :(得分:1)

我想知道这对于显式连接而不是in语句是如何工作的:

SELECT 20 AS [Priority], clientid AS ClientId
FROM clients.dbo.ViewClientsByFullname v WITH (NOLOCK) left outer join
     (SELECT distinct COALESCE(ParentName + ' ','') + @lastTerm AS Name
      FROM dbo.DiminuitiveNames WITH (NOLOCK) 
      WHERE Name=@firstTerm OR ParentName=@firstTerm
    ) c1
    on v.fullname = c1.name left outer join
    (select distinct COALESCE(Name + ' ','') + @lastTerm AS Name 
     FROM dbo.DiminuitiveNames WITH (NOLOCK) 
     WHERE ParentName IN (SELECT ParentName 
                          FROM dbo.DiminuitiveNames WITH (NOLOCK) 
                          WHERE Name=@firstTerm OR ParentName=@firstTerm
                         )
    ) c2
    on v.fullname = c2.name
WHERE @totalKeywords > 1 AND (c1.name is not null or c2.name is not null)

答案 1 :(得分:0)

尝试新的查询

SELECT 20 AS [Priority],clientid AS ClientId
FROM clients.dbo.ViewClientsByFullname WITH (NOLOCK)
WHERE @totalKeywords > 1
  AND EXISTS (
              SELECT 1
              FROM dbo.DiminuitiveNames WITH (NOLOCK) 
              WHERE Name=@firstTerm OR ParentName=@firstTerm
                AND (COALESCE(ParentName + ' ','') + @lastTerm = fullname
                  OR COALESCE(Name + ' ','') + @lastTerm = fullname)    
              )