Это на SQL Server 2014, но я наблюдаю такое же поведение в 2008, 2012 и 2016 годах, а также в Sybase ASE 15.7.
У меня есть простой запрос, который выглядит следующим образом :
SELECT myField
FROM myTable
WHERE someIndexedField = @myParam
Если я запускаю этот запрос из SSMS (заменяя @myParam на 'myValue'), запрос выполняется менее чем за секунду, потому что someIndexedField проиндексирован, и поиск должен быть очень быстрым. Однако, если я создаю тот же запрос, что и параметризованная строка запроса в программе C#, запрос занимает от 20 до 30 секунд. Анализ, проведенный администраторами баз данных, показывает, что план запроса НЕ использует индекс для столбца someIndexedField, а вместо этого выполняет сканирование таблицы.
Даже незнакомец, если я делаю точно такой же параметризованный запрос, а вместо этого меняю его немного об этом:
DECLARE @_myParam char(13)
SET @_myParam = @myParam
SELECT myField
FROM myTable
WHERE someIndexedField = @_myParam
... эта версия неожиданно снова использует индекс, и производительность возвращается к доле времени ответа менее секунды. Я вижу такое же поведение в запросах различной сложности, но не на 100% последовательно для разных запросов - иногда сервер решает использовать индекс. Это, однако, согласовано для любого данного запроса. Я никогда не знаю, какие запросы будут затронуты, прежде чем пытаться их, но если данный запрос имеет эту проблему, он всегда есть проблема. Кроме того, запрос, который не имеет проблемы, кажется, никогда не будет его разрабатывать позже.
Еще одна странная вещь, которую я заметил, заключается в том, что иногда изменение общей длины запроса фактически влияет на то, как это поведение обнаруживается. У меня был один пример, когда добавление дополнительных возвратов каретки в запрос (по сути, двойной интервал) фактически приводило к тому, что сервер неожиданно начал использовать индексы, как и ожидалось. Буквально НЕТ КОДА не было изменено. Однако я не смог определить точную длину, на которой это произошло. Кроме того, это конкретное «решение», похоже, работает только на Sybase ASE - мне не удалось воспроизвести его на SQL сервере.
(кстати, я также могу использовать подсказку для pu sh сервера использовать соответствующий индекс, и это также решает проблему.Однако, подсказки индекса, как правило, не очень хорошая идея, если вы можете их избежать, и кажется, что сервер должен быть вполне способен выбрать индекс самостоятельно, особенно с такими простой запрос.)
Что здесь происходит? Почему первая версия работает так, как будто в таблице нет индексов? И почему простое помещение параметра в локально определенную переменную внезапно приводит к использованию индексов?