tags:

views:

1948

answers:

6

I use lazy connection to connect to my DB within my DB object. This basically means that it doesn't call mysql_connect() until the first query is handed to it, and it subsequently skips reconnecting from then on after.

Now I have a method in my DB class called disconnectFromDB() which pretty much calls mysql_close() and sets $_connected = FALSE (so the query() method will know to connect to the DB again). Should this be called after every query (as a private function) or externally via the object... because I was thinking something like (code is an example only)

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

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

Now if it was closing after every query, would this slow it down a lot as opposed to me just adding this line to the end

$db->disconnectFromDB();

Or should I just include that line above at the very end of the page?

What advantages/disadvantages do either have? What has worked best in your situation? Is there anything really wrong with forgetting to close the mySQL connection, besides a small loss of performance?

Appreciate taking your time to answer.

Thank you!

+11  A: 

As far as I know, unless you are using persistent connections, your MySQL connection will be closed at the end of the page execution.

Therefore, you calling disconnect will add nothing and because you do the lazy connection, may cause a second connection to be created if you or another developer makes a mistake and disconnects at the wrong time.

Given that, I would just allow my connection to close automatically for me. Your pages should be executing quickly, therefore holding the connection for that small amount of time shouldn't cause any problems.

Rob Prouse
+1 to letting PHP clean up connections (I don't recommend using persistent connections).
Bill Karwin
I also recommend against using persistent connections. They have caused me nothing but trouble and hard to track down bugs in the past.
Rob Prouse
I'd also recommend you turn down the wait_timeout setting in MySQL. The default is 8 hours. Most web pages do not take that long to load.
staticsan
most? none of them takes 8 hours to load :P
pablasso
+1  A: 

You may want to look at a using persistent connections. Here are two links to help you out

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

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

grepsedawk
http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/
Bill Karwin
+5  A: 

I just read this comment on PHP website regarding persistent connection and it might be interesting to know:

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)

(I was not the one that wrote the text above)

Nazgulled
Where did that come from? Copying from elsewhere without so much as a citation is not proper.
Andrew Medico
There's information built on thoroughly out of date versions of mysql in there. I would view it skeptically. Also with regard to PHP.
le dorfier
In addition to temp tables, don't forget MySQL user variables, session settings like CHARSET, and LAST_INSERT_ID(). These are scoped to the connection, so the next web request that gets that persistent connection may "see" the state of another user's DB session!
Bill Karwin
To add to what Bill Karwin said, there's also a setting somewhere in mysqli to turn debug tracing on which is scoped to the connection. I haven't used it in a while but the effect was something along the lines of sending the full text of every query straight to the browser output.
Ant P.
Andrew Medico: I stated I didn't write it myself and that I took it out from the PHP website. So, what's the problem? If you really want the link: http://us2.php.net/manual/en/function.mysql-pconnect.php#85670
Nazgulled
It's a mix of five-year-old user comments to a note in the PHP manual about MyISAM behavior. I'd look for newer information closer to the source.
le dorfier
The first two read to me as "if you write sloppy code, persistent connections may become a problem". IMO, that means the correct solution is "don't write sloppy code", not "don't use persistent connections".
Dave Sherohman
+3  A: 

Don't bother disconnecting. The cost of checking $_connected before each query combined with the cost of actually calling $db->disconnectFromDB(); to do the closing will end up being more expensive than just letting PHP close the connection when it is finished with each page.

Reasoning:

1: If you leave the connection open till the end of the script:

  • PHP engine loops through internal array of mysql connections
  • PHP engine calls mysql_close() internally for each connection

2: If you close the connection yourself:

  • You have to check the value of $_connected for every single query. This means PHP has to check that the variable $_connected A) exists B) is a boolean and C) is true/false.
  • You have to call your 'disconnect' function, and function calls are one of the more expensive operations in PHP. PHP has to check that your function A) exists, B) is not private/protected and C) that you provided enough arguments to your function. It also has to create a copy of the $connection variable in the new local scope.
  • Then your 'disconnect' function will call mysql_close() which means PHP A) checks that mysql_close() exists and B) that you have provided all needed arguments to mysql_close() and C) that they are the correct type (mysql resource).

I might not be 100% correct here but I believe the odds are in my favour.

too much php
highly speculative assertions.
le dorfier
@doofledorfer- Do you think he is incorrect?
alex
Yes. PHP is going to need to make the same check and the same call, and you've exposed the system to the open connection constraint longer than you needed to. (And esthetically, it's sloppy, but that's another issue.)
le dorfier
What is your suggestion doofledorfer... ditch the disconnect but leave the lazy connector? That's what I've currently done.
alex
I think you're fine. I disagree with the logic being used in this answer. Right answer, Unsupported (and not particularly credible) reasoning.
le dorfier
+1  A: 

The basic unit of execution presumably is an entire script. What you first of all are wanting to apply resources (i.e. the database) to, efficiently and effectively, is the entirety of a single script.

However, PHP, Apache/IIS/whatever, have lives of their own; and they are capable of using the connections you open beyond the life of your script. That's the signficance of persistent (or pooled) connections.

Back to your script. It turns out you have a great deal of opportunity to be creative about using that connection during its execution.

The typical naive script will tend to hit the connection again and again, picking up locally appropriate scraps of data associated with given objects/modules/selected options. This is where procedural methodology can inflict a penalty on that connection by opening, requesting, receiving, and closing. (Note that any single query will remain alive until it is explicitly closed, or the script ends. Be careful to note that a connection and a query are not the same thing at all. Queries tie up tables; connections tie up ... connections (in most cases mapped to sockets). So you should be conscious of proper economy in the use of both.

The most economical strategy with regard to queries is to have as few as possible. I'll often try to construct a more or less complex joined query that brings back a full set of data rather than parceling out the requests in small pieces.

le dorfier
+1  A: 

Using a lazy connection is probably a good idea, since you may not need the database connection at all for some script executions.

On the other hand, once it's open, leave it open, and either close it explicitly as the script ends, or allow PHP to clean up the connection - having an open connection isn't going to harm anything, and you don't want to incur the unnecessary overhead of checking and re-establishing a connection if you are querying the database a second time.

Rob