Который предоставляет лучшей производительности одно большое соединение или несколько запросов?

у меня есть таблица, названная заказами. один столбец на порядке является customer_id
у меня есть таблица, названная клиентами с 10 полями

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

Опция 1:

a. сначала запросите таблицу заказов. b. цикл через записи и запрос таблица людей для получения записей для человека

это было бы чем-то как:

 Select * from APplications

 Select * from Customer where id = 1
 Select * from Customer where id = 2
 Select * from Customer where id = 3
 Select * from Customer where id = etc . . .

Опция 2:

a. сделайте соединение на всех полях

очевидный № 2, потому что Вы только делаете один запрос по сравнению с 1 + [numberOforders] запросы (могли быть сотни или больше),

Это было бы чем-то как:

 Select * from Applications a, Customers c
 Innerjoin c.id = a.customerID

мой основной вопрос, что, если у меня было 10 других таблиц, которые были выключены из таблицы заказов (подобный клиенту), где у Вас был идентификатор в таблице порядка. если Вы делаете единый запрос, который присоединяется к этим 10 таблицам или в какой-то момент является этим неэффективный, делают к этому:

любые предложения помогли бы.. есть ли любая оптимизация для обеспечения высокой производительности

26
задан Doug Chamberlain 8 July 2013 в 13:49
поделиться

5 ответов

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

Лучше всего сначала попробовать самый простой подход (большое соединение) и посмотреть, насколько хорошо он работает. Если он работает хорошо, то отлично - готово. Если он работает плохо, профилируйте запрос и найдите недостающие индексы в своих таблицах.

Ваш вариант №1 вряд ли будет работать хорошо из-за большого количества сетевых циклов приема-передачи (как упоминалось в Anijhaw). Иногда это называют проблемой «выбрать N + 1» - вы делаете один SELECT, чтобы получить список N приложений, а затем выполняете N SELECT в цикле, чтобы получить клиентов. Этот непрерывный цикл является естественным для прикладных программистов; но SQL работает намного лучше, когда вы работаете с целыми наборами данных одновременно.

Если вариант № 2 медленный даже при хорошей индексации, вы можете захотеть изучить кеширование. Вы можете кэшировать в базе данных (используя сводную таблицу или материализованное / индексированное представление), в приложении (если оперативной памяти достаточно) или на выделенном сервере кеширования, таком как memcached. Конечно, это зависит от того, насколько актуальными должны быть результаты вашего запроса. Если все должно быть полностью обновлено, то любой кеш должен обновляться всякий раз, когда обновляются базовые таблицы - это становится сложным и становится менее полезным.

Это похоже на отчетный запрос, а отчеты часто не работают. не обязательно в реальном времени. Так что кеширование может вам помочь.

В зависимости от вашей СУБД, стоит подумать еще о влиянии этого запроса на другие запросы, обращающиеся к той же базе данных. Если ваша СУБД позволяет читателям блокировать писателей, то этот запрос может предотвратить обновление таблиц, если для его выполнения потребуется много времени. Это было бы плохо. У Oracle нет этой проблемы, как и у SQL Server при запуске "

19
ответ дан 28 November 2019 в 07:50
поделиться

Если этот customer_id уникален в вашей таблице клиентов (а другие идентификаторы уникальны в других таблицах), то ваш запрос возвращает только 1 строку для каждого приложения, тогда выполнение одного SELECT, безусловно, более эффективно.

Объединение всех требуемых клиентов в один запрос будет оптимизировано, в то время как использование большого количества отдельных запросов SELECT не может.

РЕДАКТИРОВАТЬ
Я пробовал это с Oracle PL / SQL с 50 000 приложений и 50 000 подходящих клиентов .

Решение с выбором всего в одном запросе заняло
0,172 с

Решение с выбором каждого клиента в одном SELECT заняло
1,984 с

И это, скорее всего, ухудшается с другими клиентами или когда доступ по сети.

7
ответ дан 28 November 2019 в 07:50
поделиться

На мой взгляд, одиночное соединение все равно будет быстрее, потому что СУБД всегда будет выполнять предложения where перед выполнением соединений. Это означает, что до того, как произойдет объединение, все задействованные таблицы уже были сокращены до минимально возможного размера.

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

Ключевым моментом здесь является то, что все таблицы перед объединением обрезаются до минимального размера, и что мы используем внутренние объединения. Если оба этих условия изменятся (некоторые внешние соединения допустимы), у вас могут возникнуть проблемы.

1
ответ дан 28 November 2019 в 07:50
поделиться

Одиночное соединение должно быть быстрее по двум основным причинам.

Если вы запрашиваете по сети, то использование количества запросов вместо одного запроса связано с накладными расходами.

A соединение будет оптимизировано внутри СУБД с помощью оптимизатора запросов, поэтому будет быстрее, чем выполнение нескольких запросов.

2
ответ дан 28 November 2019 в 07:50
поделиться

, если вы выполните один запрос, который объединяет эти 10 таблиц или в какой-то момент он окажется неэффективным

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

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

1
ответ дан 28 November 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: