PHP mySQL - когда лучше всего отключиться от базы данных?

Я использую ленивое соединение для подключения к моей БД в моем объекте БД. Это в основном означает, что он не вызывает mysql_connect () до тех пор, пока ему не будет передан первый запрос, и впоследствии он пропускает повторное подключение с этого момента.

Теперь у меня есть метод в моем классе БД под названием disconnectFromDB(), который в значительной степени вызывает mysql_close() и устанавливает $_connected = FALSE (так что метод query() будет знать, что нужно снова подключиться к БД). Должен ли он вызываться после каждого запроса (как частная функция) или извне через объект ... потому что я думал что-то вроде (код является только примером)

$students = $db->query('SELECT id FROM students');

$teachers = $db->query('SELECT id FROM teachers');

Теперь, если бы он закрывался после каждого запроса, это сильно замедлило бы его, в отличие от меня, просто добавляющего эту строку в конец

$db->disconnectFromDB();

Или я должен просто включить эту строку выше в самый конец страницы?

Какие преимущества / недостатки есть у каждого из них? Что лучше всего сработало в вашей ситуации? Что действительно плохого в том, чтобы забыть закрыть соединение mySQL, кроме небольшой потери производительности?

Цените время, потраченное на ответ.

Спасибо!

Надеюсь, ваше приложение разбито на разделы лучше, чем предполагают ваши примеры. Было бы легче отслеживать ваше ленивое соединение, если бы оно было инкапсулировано.

dkretz 03.12.2008 06:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
18
1
15 749
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Насколько мне известно, если вы не используете постоянные соединения, ваше соединение MySQL будет закрыто в конце выполнения страницы.

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

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

+1 к разрешению PHP очищать соединения (я не рекомендую использовать постоянные соединения).

Bill Karwin 03.12.2008 05:43

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

Rob Prouse 03.12.2008 05:45

Я также рекомендую вам отключить параметр wait_timeout в MySQL. По умолчанию 8 часов. Большинство веб-страниц загружаются не так много времени.

staticsan 03.12.2008 08:08

самый? ни один из них не загружается за 8 часов: P

pablasso 14.05.2009 00:16

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

http://us2.php.net/manual/en/features.persistent-connections.php

http://us2.php.net/manual/en/function.mysql-pconnect.php

mysqlperformanceblog.com/2006/11/12/…
Bill Karwin 03.12.2008 05:42

Я только что прочитал этот комментарий на веб-сайте PHP относительно постоянного соединения, и было бы интересно узнать:

Here's a recap of important reasons NOT to use persistent connections:

  • When you lock a table, normally it is unlocked when the connection closes, but since persistent connections do not close, any tables you accidentally leave locked will remain locked, and the only way to unlock them is to wait for the connection to timeout or kill the process. The same locking problem occurs with transactions. (See comments below on 23-Apr-2002 & 12-Jul-2003)

  • Normally temporary tables are dropped when the connection closes, but since persistent connections do not close, temporary tables aren't so temporary. If you do not explicitly drop temporary tables when you are done, that table will already exist for a new client reusing the same connection. The same problem occurs with setting session variables. (See comments below on 19-Nov-2004 & 07-Aug-2006)

  • If PHP and MySQL are on the same server or local network, the connection time may be negligible, in which case there is no advantage to persistent connections.

  • Apache does not work well with persistent connections. When it receives a request from a new client, instead of using one of the available children which already has a persistent connection open, it tends to spawn a new child, which must then open a new database connection. This causes excess processes which are just sleeping, wasting resources, and causing errors when you reach your maximum connections, plus it defeats any benefit of persistent connections. (See comments below on 03-Feb-2004, and the footnote at http://devzone.zend.com/node/view/id/686#fn1)

(Текст выше написал не я)

Откуда это пришло? Копирование из других источников без цитирования неуместно.

nobody 03.12.2008 05:59

Там есть информация, основанная на полностью устаревших версиях mysql. Я бы отнесся к этому скептически. Также что касается PHP.

dkretz 03.12.2008 06:17

В дополнение к временным таблицам не забудьте пользовательские переменные MySQL, параметры сеанса, такие как CHARSET и LAST_INSERT_ID (). Они привязаны к соединению, поэтому следующий веб-запрос, который получит это постоянное соединение, может "увидеть" состояние сеанса БД другого пользователя!

Bill Karwin 03.12.2008 06:18

Чтобы добавить к тому, что сказал Билл Карвин, где-то в mysqli есть параметр, позволяющий включить трассировку отладки, которая привязана к соединению. Я не использовал его некоторое время, но эффект был чем-то вроде отправки полного текста каждого запроса прямо в вывод браузера.

user42092 03.12.2008 06:27

Эндрю Медико: Я заявил, что не писал его сам, и что я взял его с веб-сайта PHP. Так в чем проблема? Если очень нужна ссылка: us2.php.net/manual/en/function.mysql-pconnect.php#85670

rfgamaral 03.12.2008 06:35

Это смесь комментариев пятилетних пользователей к примечанию в руководстве по PHP о поведении MyISAM. Я бы поискал более свежую информацию поближе к источнику.

dkretz 03.12.2008 08:49

Первые два читаются мне как «если вы напишете небрежный код, постоянные соединения могут стать проблемой». ИМО, это означает, что правильное решение - «не писать небрежный код», а не «не использовать постоянные соединения».

Dave Sherohman 04.12.2008 08:54

Не беспокойтесь об отключении. Стоимость проверки $_connected перед каждым запросом в сочетании со стоимостью фактического вызова $db->disconnectFromDB(); для закрытия в конечном итоге будет дороже, чем просто позволить PHP закрыть соединение, когда оно завершается с каждой страницей.

Рассуждение:

1: Если вы оставите соединение открытым до конца скрипта:

  • Движок PHP перебирает внутренний массив соединений mysql
  • Движок PHP вызывает mysql_close () внутренне для каждого соединения

2: Если вы закрываете соединение самостоятельно:

  • Вы должны проверять значение $_connected для каждого запроса. Это означает, что PHP должен проверить, что переменная $_connected A) существует, B) является логическим значением и C) имеет значение true / false.
  • Вы должны вызвать функцию «разъединения», а вызовы функций - одна из самых дорогих операций в PHP. PHP должен проверить, что ваша функция A) существует, B) не является частной / защищенной и C) что вы предоставили достаточно аргументов для своей функции. Он также должен создать копию переменной $ connection в новой локальной области.
  • Затем ваша функция отключения вызовет mysql_close (), что означает, что PHP A) проверяет, существует ли mysql_close () и B) что вы предоставили все необходимые аргументы mysql_close () и C), что они являются правильным типом (ресурс mysql).

Возможно, я здесь не на 100% прав, но считаю, что шансы в мою пользу.

в высшей степени спекулятивные утверждения.

dkretz 03.12.2008 06:24

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

dkretz 03.12.2008 08:40

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

alex 03.12.2008 08:55

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

dkretz 03.12.2008 09:47

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

Однако у PHP, Apache / IIS / чего угодно есть своя собственная жизнь; и они способны использовать связи, которые вы открываете за пределами жизненного цикла вашего сценария. В этом важность постоянных (или объединенных) соединений.

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

Типичный наивный сценарий будет иметь тенденцию снова и снова подключаться к соединению, собирая локально соответствующие фрагменты данных, связанных с заданными объектами / модулями / выбранными параметрами. Именно здесь процедурная методология может наложить штраф на это соединение путем открытия, запроса, получения и закрытия. (Обратите внимание, что любой отдельный запрос будет оставаться активным до тех пор, пока он не будет явно закрыт или пока сценарий не завершится. Обратите внимание, что соединение и запрос - это совсем не одно и то же. Запросы связывают таблицы; соединения связывают ... соединения (в большинстве случаев привязаны к сокетам.) Таким образом, вы должны осознавать необходимость экономии при использовании обоих.

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

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

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

Другие вопросы по теме