Почему плохой практикой является создание нескольких подключений к базе данных за один запрос? - PullRequest
1 голос
/ 26 августа 2008

Дискуссия о синглетонах в PHP заставляет меня задумываться над этой проблемой все больше и больше. Большинство людей инструктируют, что вы не должны делать кучу соединений с БД в одном запросе, и мне просто любопытно, что вы думаете. Моя первая мысль - это затраты на ваш сценарий создания такого большого количества запросов к БД, но затем я отвечаю себе вопросом: не сделает ли несколько соединений одновременные запросы более эффективными?

Как насчет некоторых ответов (с доказательствами, люди) от некоторых людей в курсе?

Ответы [ 5 ]

6 голосов
/ 26 августа 2008

Соединения с базой данных являются ограниченным ресурсом. Некоторые БД имеют очень низкий предел соединения, и потеря соединений является серьезной проблемой. Потребляя много соединений, вы можете заблокировать другие для использования базы данных.

Кроме того, добавление тонны дополнительных соединений в БД ничего не поможет, если на сервере БД нет свободных ресурсов. Если у вас есть 8 ядер, и только одно используется для удовлетворения запроса, тогда, конечно, может помочь установление другого соединения. Скорее всего, вы уже используете все доступные ядра. Вы также, вероятно, используете один и тот же жесткий диск для каждого запроса БД и добавляете дополнительную конкуренцию за блокировку.

Если в вашей БД есть что-то похожее на высокую загрузку, добавление дополнительных соединений не поможет. Это было бы похоже на создание дополнительных потоков в приложении со слепой надеждой на то, что дополнительный параллелизм сделает обработку более быстрой. Он может в некоторых определенных обстоятельствах, но в других случаях он просто замедлит вас, когда вы перебиваете жесткий диск, тратите время на переключение задач и вводите издержки синхронизации.

3 голосов
/ 26 августа 2008

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

Доказательства сложнее найти, но учтите следующее ...

Допустим, для установления соединения требуется х микросекунд.

Теперь вы хотите сделать несколько запросов и получать данные туда-сюда. Допустим, что разница во времени передачи незначительна между одним соединением и многими (просто ради аргумента).

Теперь предположим, что для закрытия соединения требуется y микросекунд.

Открытие одного соединения займет x + y микросекунд служебных данных. Открытие многих займет n * (x + y). Это задержит ваше исполнение.

2 голосов
/ 26 августа 2008

Настройка соединения с БД обычно довольно тяжелая. За кулисами происходит много всего (разрешение DNS / TCP-соединение / рукопожатие / аутентификация / фактический запрос) .

Однажды у меня возникла проблема с какой-то странной конфигурацией DNS, из-за которой каждое TCP-соединение занимало несколько секунд, прежде чем оно заработало. Моя процедура входа в систему (из-за сложной архитектуры) потребовала 3 разных подключения к БД. С этой проблемой вход в систему длился вечно. Затем мы реорганизовали код, чтобы он проходил только через одно соединение.

1 голос
/ 26 августа 2008

Мы обращаемся к Informix из .NET и используем несколько соединений. Если мы не запускаем транзакцию для каждого соединения, она часто обрабатывается в пуле соединений. Я знаю, что это очень специфично для бренда, но безмолвный доступ большинства (?) Систем баз данных будет объединять соединения в меру своих возможностей.

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

0 голосов
/ 26 августа 2008

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

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

Асинхронные запросы уменьшают стоимость соединения за счет более быстрого времени запроса / ответа ... поскольку вы не можете легко достичь этого в PHP без некоторой многопоточности, тогда снижение производительности будет больше, чем просто повторное использование того же соединения.

это мои 2 цента ...

...