Что лучше для этого запроса, "Внутреннее соединение" или "Где" - PullRequest
0 голосов
/ 27 января 2010

У меня есть этот запрос 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 его именами из другой таблицы, это заняло много времени.

например. 123 [последний идентификатор в strIDS] является taskID из CRSTask, имеет отношение один к одному с CRSTaskReceiver и TaskReceiver имеет отношение один к одному с Portal_Users_View (id, userName) -Мне нужно заменить 123 на эквивалентное имя пользователя -Я сделал это с помощью Joins .. это занимает много времени, также используя Где между таблицами много времени

1 Ответ

0 голосов
/ 11 декабря 2011

Чтобы ответить на ваш вопрос: по моему мнению, JOIN лучше в 99% случаев, так как они более четко показывают основную модель данных. Это облегчает поддержку кода, а оптимизатору запросов также легче придумать достойный план запросов.

Я не большой поклонник 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 () сервер не может правильно использовать свои индексы, и у вас может быть самое странное поведение с точки зрения производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...