哪个是这个查询的最佳选择,“内部联接”或“何处”

时间:2010-01-27 08:17:55

标签: sql tsql optimization

我有这个SQL查询

SELECT t.id AS taskid,
       STUFF(
           (
               SELECT ',' + x.tID
               FROM   (
                          SELECT CAST(id AS VARCHAR(200)) AS tid
                          FROM CRSTask c WHERE c.ParentTask = 
                          7562 -- comment this line
                      ) x
                      FOR XML PATH('')
           ),
           1,
           1,
           ''
       ) AS strIDS
FROM   CRSTask t
WHERE t.ParentTask IS NULL
AND t.id = 7562 -- comment this line  

此查询的结果将是:

 id          strIDS  
7562    7615,7616,7617,7618,7619,7620,7621,7631,7632,123

这很好,但是当我尝试用另一个表中的名字替换strIDS时,需要很多时间。

e.g。 123 [strIDS中的最后一个id]是来自CRSTask的taskID,与CRSTaskReceiver有一对一的关系 和taskReceiver有一对一的关系到Portal_Users_View(id,userName) - 我需要用等效的userName替换123 - 我使用了连接...它需要花费很多时间,也使用表之间的位置需要很多时间

1 个答案:

答案 0 :(得分:0)

回答你的问题:在我看来,99%的案例中JOIN更好,因为它们更清楚地显示了基础数据模型。这样可以更轻松地维护代码,查询优化器也可以更轻松地提出合适的查询计划。

我不是UDF的忠实粉丝,但在这种情况下,它可能是解决问题的最简单方法,因为MSSQL本身不支持聚合字符串:

-- create User Defined Function to fetch list of names for given taskid
CREATE FUNCTION dbo.fn_names_from_taskid ( @taskid int )
RETURNS nvarchar(max)
AS
    BEGIN
        DECLARE @result nvarchar(max)
        SELECT @result = ''

        SELECT @result = @result 
                       +  Portal_Users_View.ArabicName + ','
          FROM Portal_Users_View 
          JOIN CRSTaskReceiver 
            ON CRSTaskReceiver.ReceiverID = Portal_Users_View.ID
          JOIN CRSTask c 
            ON CAST(c.id AS VARCHAR(200)) = CRSTaskReceiver.CRSTaskID -- cast really necessary?
           AND c.ParentTask = @taskid 

        -- strip last comma (if present)
        SELECT @result = (CASE WHEN Right(@result, 1) = ',' THEN Left(@result, Len(@result) - 1) ELSE @result END)

        Return(@result)
    END

GO

-- usage    
SELECT taskid    = t.id,
       nameslist = dbo.fn_names_from_taskid (t.id)
  INTO #test
 WHERE id = 7652

PS:我试图从上面的代码解释你的数据模型,你需要仔细检查它!

PS:Cast()真的有必要吗?我会假设所有id字段都存储为int?!?如果是这样(并且使用正确的索引)那些连接应该是“非常快”,但是使用Cast(),服务器无法正确使用其索引,并且您可能在性能方面具有最奇怪的行为。