Как заставить SQL использовать критерии, при которых используются операторы group by и like - PullRequest
1 голос
/ 10 августа 2011

У меня есть представление SQL, которое содержит группу по. Я пытаюсь выбрать из вида, используя как. Столбец, который я выбираю, индексируется, но SQL настаивает на создании временной таблицы со всеми строками в таблице и последующей фильтрации по критериям where. (медленно) Как мне получить фильтр FIRST?

Пример

Показать определение :

SELECT ListCode, SUM(CASE
    WHEN ListStatus = 'A' THEN 1
      ELSE 0
      END) Active
FROM ListParticipation
GROUP BY ListCode

Выберите

SELECT *
FROM ListParticipationView
WHERE ListCode like '%ReallyCoolList%'

Кстати, если я использую аналогичные критерии без начального подстановочного знака, план SQL показывает фильтрацию, происходящую до суммирования группы.

Ответы [ 3 ]

2 голосов
/ 10 августа 2011

Ваш критерий не SARGable, то есть он не может использовать индекс.

Использование LIKE с % в начале строки сравнения гарантирует сканирование таблицы. SQL должен проверять все поле в каждой строке, чтобы оценить соответствие.

Если ваша ListCode очень длинная строка, возможно, вам следует сделать ее int, которая является PK в таблице поиска. Тогда вы могли бы оценить:

WHERE Listcode IN (1, 3, 4, 6) и используйте индекс.

1 голос
/ 10 августа 2011

Сначала не выполняется фильтрация, поскольку начальный подстановочный знак не позволяет использовать индекс. По сути, он должен искать всю строку - так что он все еще должен искать каждую строку , потому что индекс char или varchar обычно начинается с первого символа ... Это было бы примерно эквивалентно удивлению, почему не используется индекс из нескольких столбцов, когда критерии выбора ограничиваются только на основе второго или третьего столбца, а не первого.

Если у вас есть повторяющиеся ListCode с (как, по-видимому, имеет место), рассмотрите возможность их извлечения в свою собственную таблицу, а затем поместите идентификатор новой таблицы как listCodeId в таблицу ListParticipation (и замените индекс тоже). Если у вас есть достаточно умный оптимизатор, он найдет все listCode в своей таблице, которые соответствуют заданной строке с подстановочными символами (должно быть уникальным, поэтому, пожалуйста, имейте уникальное ограничение), затем используйте его для запроса индекса fk на listCodeId. Должно быть намного более производительным.

0 голосов
/ 10 августа 2011

Я вижу, вы узнали, почему представления часто являются плохой идеей.Становится намного хуже, если они называют другие взгляды.Если оператор SQL, непосредственно обращающийся к таблице, быстрее, используйте это.Но не используйте предложение where с оператором like, в котором в качестве первого символа используется подстановочный знак.Выполнение этого для любого значения, отличного от одноразового запроса, означает, что вам необходимо использовать другой метод, например:

  1. , который вам нужен для исправления дизайна
    или
  2. , который необходимо использоватьполнотекстовая индексация

Если вы храните такие данные, как «test, mytest, еще один глупый тест», в одном столбце и используете предложение like, чтобы найти все значения «mytest», то вам нужно нормализовать таблицыи сохраняйте данные правильно.

Если у вас есть пользователи, которые ищут термины, они могут не знать точное название (скажем, длинное официальное название аэропорта, например, «Национальный аэропорт Рональда Рейгана», и поиск может быть «Национальный»).Airport '), а затем используйте полнотекстовое индексирование.

Если вы ставите% вперед без какой-либо конкретной причины, прекратите это делать.

...