Как избежать слишком большого количества объединений?

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

В настоящее время у меня есть очень сложный запрос, который объединяет 11 таблиц, и производительность очень низкая (даже с индексами и обновленной статистикой). Используя Entity Framework Profiler, я получил предложение уменьшить количество объединений и вместо этого выполнить несколько отдельных запросов: ссылка.

Каждое соединение требует от базы данных дополнительной работы, а сложность и стоимость запроса быстро растут с каждым дополнительным соединением. Хотя реляционная база данных оптимизирована для обработки объединений, зачастую более эффективно выполнять несколько отдельных запросов, а не один запрос с несколькими объединениями.

Как изменить следующий пример, чтобы повысить производительность?

select  *
from   Blogs blog0_
       inner join Posts posts1_
         on blog0_.Id = posts1_.BlogId
       inner join Comments comments2_
         on posts1_.Id = comments2_.PostId
       inner join Users user3_
         on posts1_.UserId = user3_.Id
       inner join UsersBlogs users4_
         on blog0_.Id = users4_.BlogId
       inner join Users user5_
         on users4_.UserId = user5_.Id

person Ricardo    schedule 24.09.2014    source источник
comment
Ваш запрос, вероятно, в порядке, если у вас есть соответствующие индексы. Ссылка сильно вводит в заблуждение.   -  person Gordon Linoff    schedule 24.09.2014
comment
Больше подходит для нашего братского сайта. Обзор кода   -  person Daryl Gill    schedule 24.09.2014
comment
Соединения на самом деле являются одной из самых дешевых вещей, которые вы можете сделать на сервере sql. Количество записей результатов может привести к проблемам.   -  person Lynn Crumbling    schedule 24.09.2014
comment
Выбор *, вероятно, не очень хорошая идея. Вы должны выбрать только те столбцы, которые вам нужны. Это также может повлиять на производительность, хотя обычно это не является большим фактором, но иногда это может быть.   -  person Gary Walker    schedule 24.09.2014
comment
Одиннадцать джоинов — это довольно простое обстоятельство — привыкайте. Теперь, когда вы начинаете приближаться к 150 или 200 таблицам в ваших соединениях, могут быть уместны серьезные мысли о редизайне; до тех пор вы получаете настолько большую эффективность от уменьшения объема данных, что должны просто наслаждаться этим.   -  person Pieter Geerkens    schedule 24.09.2014
comment
+1 к предложению «ВЫБЕРИТЕ *». Кроме того, как предлагает профилировщик, я бы попытался разбить запрос, чтобы вы удаляли записи с помощью подзапросов, начиная с самых больших наборов результатов и спускаясь вниз, чтобы последнее соединение в верхней части кучи имело дело с минимально возможное количество записей. вы также можете получить преимущество в производительности, используя различные соединения в зависимости от цели каждого подзапроса: w3schools.com/sql/sql_join.asp   -  person Tim    schedule 24.09.2014
comment
Сначала попробуйте и посмотрите, есть ли у вас проблема. Иногда материализация частичного объединения некоторых таблиц во временную таблицу может помочь, если оценки неверны из выходных данных одного объединения, влияющих на последующие варианты объединения. Для запроса с 12 соединениями количество возможных порядков соединения составляет 28 158 588 057 600. Кроме того, каждое соединение может состоять из трех возможных алгоритмов (хеширование, вложенные циклы, слияние).   -  person Martin Smith    schedule 24.09.2014


Ответы (1)


Есть несколько способов минимизировать (оптимизировать) количество соединений таблиц:

  • Убедитесь, что вы хотите и какие таблицы требуются.
  • Также убедитесь, что таблицы приведены в нормализованной форме.

Инкапсулируйте несколько объединений, используя: -

  • Использование КТР
  • Использование временных таблиц
  • Взгляды

Подробную информацию о таблицах CTE и Temp можно найти по ссылкам Общее табличное выражение, представление. Для временной таблицы просто добавьте «#» перед именем таблицы и вставьте нужные данные из соединений, а затем используйте их, но в том же сеансе.

person Mr. K    schedule 22.08.2016
comment
Представления бесполезны, если они являются результатом нескольких объединений. - person Billal Begueradj; 05.06.2019
comment
@Begueradj, создав индексированное представление, вы можете повысить производительность запросов. Так что это не бесполезно. - person Mr. K; 13.06.2019