У меня есть большая таблица (от десятков до сотен миллионов записей), которую мы разбили по соображениям производительности на активные и архивные таблицы, используя прямое сопоставление полей и выполняя процесс архивирования каждую ночь.
В некоторых местах нашего кода нам нужно запускать запросы, которые объединяют активные и архивные таблицы, почти неизменно фильтруемые одним или несколькими полями (которые мы явно поместили в обе таблицы). Для удобства было бы целесообразно иметь такой вид:
create view vMyTable_Combined as
select * from MyTable_Active
union all
select * from MyTable_Archive
Но если я запускаю запрос, как
select * from vMyTable_Combined where IndexedField = @val
он объединит все, от Active и Store до фильтрации @val
, что снизит производительность.
Есть ли какой-нибудь умный способ заставить два подзапроса объединения просматривать каждый фильтр @val
до того, как они создадут объединение?
Или, может быть, есть какой-то другой подход, который вы бы предложили, чтобы достичь того, чего я добиваюсь, то есть простой и эффективный способ получения набора записей объединения, отфильтрованного по индексированному полю?
РЕДАКТИРОВАТЬ: вот план выполнения (и вы увидите реальные имена таблиц здесь):
Как ни странно, активная таблица на самом деле использует правильный индекс (плюс поиск RID?), Но архивная таблица выполняет сканирование таблицы!
источник
Ответы:
Комментарии к вопросу показывают, что проблема заключается в том, что тестовая база данных, которую ОП использовал для разработки запроса, имела радикально отличающиеся характеристики данных, чем производственная база данных. В нем было намного меньше строк, а поле, используемое для фильтрации, было недостаточно избирательным.
Когда число различных значений в столбце слишком мало, индекс может быть недостаточно избирательным. В этом случае последовательное сканирование таблицы обходится дешевле, чем поиск индекса / поиск строки. Обычно при сканировании таблиц используется последовательный ввод-вывод, который намного быстрее чтения с произвольным доступом.
Часто, если запрос вернет больше, чем несколько процентов строк, дешевле будет просто выполнить сканирование таблицы, чем поиск по индексу / поиск по строке или подобную операцию, которая интенсивно использует случайный ввод-вывод.
источник
Просто чтобы добавить, что я нашел. Если вы делаете:
Затем вы можете отфильтровать поле [Active] и убедиться, что другая часть не загружена.
источник