Подтвердить что ты не робот

Что заменить левое соединение в представлении, чтобы я мог иметь индексированный вид?

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

Вопрос о соединении, где одна колонка одна сторона равна нулю

Структура и отношения таблицы очень похожи на структуру, описанную в приведенной выше ссылке.

Мне показалось, что я попал в стену здесь, так как не смог преобразовать свое левое соединение во внутреннее соединение, поскольку это исключало бы все записи с нулевыми значениями в любом из соединенных столбцов. Мои вопросы:

  • Почему индексирование не допускается при внешнем или самоподключении?
  • Есть ли какие-либо хиты производительности в этом виде неиндексированного представления?
  • Кто-нибудь знает какие-либо способы решения этой проблемы?

Я только что закончил курс SQL Server, поэтому не знаю, как продолжить. Буду признателен за любые комментарии. Приветствия.

4b9b3361

Ответ 1

Существует "обходной путь" здесь, который включает проверку для NULL в соединении и наличие значения представления NULL в таблица

Значение NULL

INSERT INTO Father (Father_id, Father_name) values(-255,'No father')

Соединение

JOIN [dbo].[son] s on isnull(s.father_id, -255) = f.father_id

Ответ 2

Вот альтернатива. Вы хотите материализованное представление A, не содержащее B. Это прямо не доступно... так что материализуйте два представления. Один из всех A и один только A с B. Тогда получим только A, не имеющий B, взяв A за исключением B. Это можно сделать эффективно:

Создайте два материализованных представления (мА и mAB) (edit: mA может быть только базовой таблицей). mA не имеет соединения между A и B (таким образом, содержащий весь период A [и, следовательно, содержащий эти записи БЕЗ совпадений в B]). mAB соединяется между A и B (таким образом, содержащий только A с B [и, следовательно, исключая эти записи без совпадений в B]).

Чтобы получить все A без совпадений в B, замаскируйте те, которые соответствуют:

with ids as (
  select matchId from mA with (index (pk_matchid), noexpand)
  except
  select matchId from mAB with (index (pk_matchid), noexpand)
)
select * from mA a join ids b on a.matchId = b.matchId;

Это должно дать левое анти-соединение с вашими кластеризованными индексами, чтобы получить идентификаторы и кластерный индекс, чтобы получить данные из мА, который вы ищете.

По сути, вы используете основное правило, что SQL намного лучше справляется с данными, которые там есть, чем данные, которые НЕ. Посредством материализации двух источников вы получаете некоторые убедительные опционы на основе набора. Вы должны взвесить стоимость этих просмотров против этих выигрышей.

Ответ 3

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

Select * 
into <REAL_TABLE>
From <VIEW>

create CLUSTERED index <INDEX_THE_FIELD> on <REAL_TABLE>(<THE_FIELD>)

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

Ответ 4

Логически вы делаете два отдельных запроса. "A LEFT JOIN B" - это просто сокращение для "(A JOIN B) UNION A"

Первый запрос - это таблица A, внутренняя соединенная с таблицей B. Это получает индексированный вид, так как здесь выполняется весь тяжелый подъем.

Второй запрос - это просто таблица A, где любой из столбцов соединения имеет значение null. Сделайте представление, которое создает те же выходные столбцы, что и первый запрос, и заполняет их нулями.

Просто объедините два результата перед их возвратом. Нет необходимости в обходном пути.

Ответ 5

Я буду работать над ответом на 1, но пока:

[2]. Вид будет не более или менее выполненным, чем эквивалентный запрос в таблицах udnerlying. Все обычные рекомендации касаются наличия индексов покрытия, предпочтительно индекса на соединенных столбцах и т.д.

[3]. Нет никакого обходного пути. Большинство ограничений на индексированные представления существуют по очень веским причинам, как только вы их копаете.

Я бы просто создал представление, как правило, и больше не делаю, если не будет определенной проблемы с производительностью.

Я попытаюсь добавить ответ за один раз, как только восстановил его в своем уме.