Оптимизировать запрос в TSQL 2005 - PullRequest
3 голосов
/ 08 декабря 2011

Мне нужно оптимизировать этот запрос, может ли он помочь мне настроить его, чтобы он быстрее возвращал данные?

В настоящее время вывод занимает где-то около 26-35 секунд.Я также создал индекс на основе таблицы вложений. Вот мой запрос и индекс:

SELECT DISTINCT o.organizationlevel, o.organizationid, o.organizationname, o.organizationcode,
      o.organizationcode + ' - ' + o.organizationname AS 'codeplusname'
 FROM Organization o
 JOIN Correspondence c ON c.organizationid = o.organizationid
 JOIN UserProfile up ON up.userprofileid = c.operatorid
WHERE c.status = '4'
  --AND c.correspondence > 0
  AND o.organizationlevel = 1
  AND (up.site = 'ALL' OR
                  up.site = up.site)
  --AND (@Dept = 'ALL' OR @Dept = up.department)
  AND EXISTS (SELECT 1 FROM Attachment a
               WHERE a.contextid = c.correspondenceid
                 AND a.context = 'correspondence'
                 AND ( a.attachmentname like '%.rtf' or  a.attachmentname like '%.doc'))
ORDER BY o.organizationcode

Я не могу просто что-либо изменить в БД из-за проблем с разрешениями, любая помощь будет высоко оценена.

Ответы [ 2 ]

1 голос
/ 08 декабря 2011

Я полагаю, что ваша головная боль исходит от этой части в конкретном случае ... например, в том месте, где существует, может быть узкое место вашей производительности.

 AND EXISTS (SELECT 1 FROM Attachment a
           WHERE a.contextid = c.correspondenceid
             AND a.context = 'correspondence'
             AND ( a.attachmentname like '%.rtf' or  a.attachmentname like '%.doc'))

Это можно записать как объединение.1005 *

Это устраняет подобное и где.поместите предложение where в bottom.it - ​​это левое соединение, поэтому a.anycolumn имеет значение null, означает, что запись не существует, и a.anycolumn не имеет значение null, означает, что запись была найдена.Если a.anycolumn не равно NULL, это будет эквивалентно истине в логике, где существует.

Редактировать, чтобы добавить: Еще одна мысль для вас ... Я не уверен, что вы пытаетесь сделать здесь ....

И (up.site = 'ALL' ИЛИ ​​up.site = up.site)

так где up.site = 'All' или 1 = 1?или действительно нужно?

и быстро справа ... Справа (столбец, целое число) дает вам символы справа от строки (я использовал 4, так что это займет 4 правых символа)указанного столбца).Я обнаружил, что это намного быстрее, чем работает оператор like.

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

Это всегда будет возвращать true, так что вы можете устранить его (и, возможно, объединить до)

    AND (up.site = 'ALL' OR up.site = up.site)  

Если вы можете жить с грязным чтением, тогда с (nolock)

И я бы попробовал Attachement как объединение.Может не помочь, но стоит попробовать.Like - это относительно дорого, и если он делает это в цикле, в котором он мог бы один раз, это действительно помогло бы.

    Join Attachment a
     on a.contextid = c.correspondenceid
     AND a.context = 'correspondence'
     AND ( a.attachmentname like '%.rtf' or  a.attachmentname like '%.doc'))  

Я знаю, что есть некоторые люди на SO, которые настаивают, что существование всегда быстрее соединения,И да, это часто быстрее, чем объединение, но не всегда.

Другой подход заключается в создании таблицы #temp с использованием

    CREATE TABLE #Temp (contextid INT PRIMARY KEY CLUSTERED);
    insert into #temp
    Select  distinct contextid
    from atachment 
     where context = 'correspondence'
     AND ( attachmentname like '%.rtf' or  attachmentname like '%.doc')) 
    order by contextid;
    go
    select ... 
    from correspondence c
    join #Temp 
       on #Temp.contextid = c.correspondenceid 
    go
    drop table #temp

Особенно, если productID является первичным ключом или частью первичногопоможет ключ при переписке, создавая PK на #temp.

Таким образом, вы можете быть уверены, что подобное выражение вычисляется только один раз.Если подобное является дорогой частью и в цикле, то это может быть танкование запроса.Я часто использую это, когда у меня довольно дорогой основной запрос, и мне нужно, чтобы эти результаты собирали справочные данные из нескольких таблиц.Если вы делаете много объединений несколько раз, оптимизатор запросов становится глупым.Но если вы передадите оптимизатору запросов PK на PK, то это не будет глупо и быстро.Обратной стороной является то, что для создания и заполнения # temp требуется около 0,5 секунды.

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