Представление SQL, производительность и счет от отношения один ко многим - PullRequest
0 голосов
/ 01 июля 2011

Мне нужна помощь в формировании базовых представлений SQL-VIEW для нескольких моих таблиц.Вот краткий обзор

  • У меня есть таблица ClaimDetail, и в ней есть несколько полей поиска, таких как StatusID, BrandID, SalespersonID и т. Д.
  • Как обычно, поля поиска соответствуютглавные таблицы, такие как MasterStatus, MasterBrand, ... {Structure: ID, Title}
  • Также есть две другие таблицы Comments и Files.Претензия может иметь несколько комментариев и несколько файлов.
  • Мне нужно отобразить панель мониторинга, которая будет списком претензий.Мне нужно отобразить заголовки из основных таблиц и количество комментариев и файлов.

Теперь у меня есть два вида этой панели, один для пользователей типа Customer, который ограничен определенными деталями иЕще один подробный вид, который предназначен для внутренних пользователей.Можно сказать, что представление Customer является подмножеством внутреннего представления.

Я вижу два варианта -

  1. Opt # 1: Создать singlevw_Internal view и использовать его для извлечения данных для обоих пользователей.
  2. Опция # 2: я создаю vw_Customer , который содержит только те поля, которые требуются для Клиента, а затем я создаю vw_Internal , который будет выглядеть как: vw_Customer INNERПРИСОЕДИНЯЙТЕСЬ к Мастер столам.Короче говоря, я расширю базовый vw_Customer, добавив больше полей.

Имеет ли вариант № 2 смысл с точки зрения скорости и производительности?Вариант № 1 прост, но, учитывая огромное количество записей, я хочу убедиться, что Клиенты не должны ждать немного дольше тех дополнительных поисков, которые не будут включены в их Dashboard.

Наконец, есть ли способ для последней функции, которую я упомянул?То есть получает количество комментариев и файлов, которое имеет отношение один ко многим с таблицей ClaimDetail .Мне просто нужно подсчитать или, по крайней мере, логическое поле, в котором указано, есть ли у заявки какие-либо комментарии или нет (то же самое для файлов) - если будет ложным, если число = 0. Я также обеспокоен влиянием на производительность из-за этой функции.

Заранее спасибо.

1 Ответ

1 голос
/ 01 июля 2011

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

Что касается агрегирования данных, общие тактики включают следующее.Сравните, сопоставьте, протестируйте и экстраполируйте, чтобы увидеть, что лучше всего подходит для вашей среды:

Подзапросы

SELECT mt.Id, st1.HowMany, st2.HowManyOther, <etc>
 from MainTable mt
  inner join (select Id, count(*) HowMany
               from SubTable1
               group by Id) st1
   on st1.Id = mt.Id
  inner join (select Id, count(*) HowMany
               from SubTable2
               group by Id) st2
   on st2.Id = mt.Id

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

count (отличный от xx)

SELECT mt.Id, count(distinct st1.UniqueKey) HowMany, count(distinct st2.UniqueKey) HowManyOther, <etc>
 from MainTable mt
  inner join SubTable1 st1
   on st1.Id = mt.Id
  inner join SubTable2
   on st2.Id = mt.Id

Для этого требуется один уникальный столбец в «subtables», и он становится беспорядочным, если у вас естьдля работы с внешними объединениями или NULL.


Добавлено


Во-первых, замена внутренних объединений (левыми) внешними объединениями в любом из указанных выше запросов приведет к счету 0+из подтаблиц, если вы уверены, что подсчет выполняется на «правильной» таблице (потому что значения NULL не подсчитываются).Чтобы выяснить, что лучше всего работает в вашей среде, вам нужно написать и протестировать оба запроса.Я бы предположил второе, поскольку первое требует сканирования таблиц в таблицах подзапросов, в то время как второе выполняет соединения и поэтому может оптимизировать лучше, но оптимизатор SQL-запросов умнее меня (потому что он знает ваши индексы и имеет гистограммы распределенияваши данные), так что вы хотите увидеть, что это такое.

Что касается «многоуровневых представлений», если я правильно следую логике, я бы рекомендовал строить Внутреннее представление как сложное / всеобъемлющеезапрос (все объединения, все соответствующие столбцы), а затем создайте представление Customer, которое, как мы надеемся, так же просто, как

SELECT <customerOnlyColumns>
 from vw_Internal
...