SQL-запрос не использует требуемый индекс в SQL Server - PullRequest
2 голосов
/ 29 ноября 2011

У меня есть два некластеризованных индекса в таблице A:

  • detected_utc index

ключевой столбец: DETECTED_UTC ASC

Включенные столбцы:APPROVAL_STATUS, IS_ROOT, AGENTGUID

  • agentguid index

Ключевой столбец: agentguid

Теперь запрос использует agentguid Индекс и 1 мин 17 сек.

Но если я укажу подсказку запроса, такую ​​как

option (table hint(A, index(DETECTED_UTC)))

Это займет 4 секунды.

Почему SQL Server не учитывает detected_utc в плане запроса.Можно ли изменить запрос, чтобы он использовал индекс detected_utc.Я не хочу указывать подсказку в своем запросе.

SELECT
    AUTO_ID
FROM
    (
      SELECT
        ROW_NUMBER() OVER ( ORDER BY A.DETECTED_UTC DESC ) AS ROWNUM
      , A.AUTO_ID
      , A.DETECTED_UTC
      FROM
        A
        INNER JOIN B
        ON A.AGENTGUID = B.AgentGUID
        LEFT JOIN C
        ON B.ParentID = C.AutoID
      WHERE
        ( DETECTED_UTC > DATEADD(day, -7, GETUTCDATE()) )
        AND ( APPROVAL_STATUS = '0' )
        AND IS_ROOT = '1'
        AND EXISTS ( SELECT
                        1
                     FROM
                        B epf
                     WHERE
                        epf.AgentGUID IS NOT NULL
                        AND epf.AgentGUID = A.AGENTGUID
                        AND epf.ParentID IN (
                        SELECT
                            AutoID
                        FROM
                            C
                        WHERE
                            AutoID IN ( SELECT
                                            NodeID
                                        FROM
                                            D
                                        WHERE
                                            D.GroupID IN ( 42 ) ) ) )
    ) AS TEMP
WHERE
    ROWNUM >= 1000
    AND ROWNUM < 1041
ORDER BY
    DETECTED_UTC DESC 

Ответы [ 2 ]

1 голос
/ 29 ноября 2011
  • Ваше СОЕДИНЕНИЕ включено AGENTGUID
  • Ваше ГДЕ использует DETECTED_UTC, APPROVAL_STATUS, IS_ROOT

Только столбец DETECTED_UTC полезен в индексе detected_utc для оптимизатора: остальные используемые столбцы являются включенными столбцами. Ваша подсказка индекса переопределяет это: я подозреваю, что вы увидите в плане поиски, катушки или сортировки с подсказкой для обхода включенных столбцов, которые не являются ключевыми столбцами в индексе

Я ожидаю, что один из них будет более полезным

(AGENTGUID, DETECTED_UTC DESC, APPROVAL_STATUS, IS_ROOT) INCLUDE (AUTO_ID)
(DETECTED_UTC DESC, AGENTGUID, APPROVAL_STATUS, IS_ROOT) INCLUDE (AUTO_ID)
0 голосов
/ 29 ноября 2011

Оптимизатор оценивает, что JOIN является наиболее избирательной частью запроса.Основываясь на этой оценке, он делает выбор в пользу того, чтобы это объединение было как можно более эффективным.

Использование подсказки индекса показывает, что оценочная избирательность неверна.Обновление статистики и перекомпиляция кода МОЖЕТ помочь в этом, но, скорее всего, не поможет: запрос очень сложный, и лучший план запроса (и, следовательно, какой индекс использовать) будет зависеть от того, какие данные существуют, и характеристик этих данных., в нескольких разных таблицах.

Я бы либо продолжил использовать подсказку (если основные характеристики ваших данных не изменятся), либо создал бы составной индекс в соответствии с рекомендациями GBN.

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