views:

385

answers:

6

Currently we are restoring MySQL connections in a $_SESSION in order to save round trip time to set up connection to MySQL,

but the problem is that the number of connections exceed the limit quickly,

so what's your guys' solution?

Do you create a new connection each time,and close that connection after using,or like me,restore it?

+3  A: 

I setup a new connection on each new page call. I do use the 1 connection throughout the page, and close it when the page is sent to the browser.

I suspect you're optimizing too early and causing yourself unneeded pain.

acrosman
Because there is a ajax request to server every 3 seconds,so I feel it necessary to do this.
Shore
Have you tried it without the storage? Does that actually cause problems or were you solving a problem you anticipated?
acrosman
It's the latter case,but I think that's reasonable.
Shore
You may be solving a problem you don't have. I would argue it's reasonable to find out if you have a problem before you solve it.
acrosman
I've a question now:why connection persist using mysql_pconnect,while not the case using mysql_connect?And is mysql_close only necessary for mysql_pconnect?Since in the case of mysql_connect,the connection will close by itself?
Shore
Because that's how mysql_pconnect does. It persists the connection "under the hood" The PHP engine/mysql driver takes care of it. Yes. mysql_close is needed. It doesn't really close the connection, just marks it as "ready to serve another request. THe docs have more details.
nos
A: 

PHP really lacks in the area of connection pooling, a very common concept in other languages/frameworks.

You can get pretty far with using mysql_pconnect . Storing a connection in a session sounds like a really bad thing though, you'd chew up way too much resources.

nos
The trouble I met is at the database level,not PHP,I think by using mysql_pconnect is similar to restoring it into $_SESSION,right?
Shore
using it in $_SESSION would limit a connection to only that session. Which might be a huge waste. using the mysql_pconnect allows anyone regardless of session to use it. That's a big win if you use a connection for as short a time as possible.
nos
Will it cause concurent trouble if using mysql_pconnect?
Shore
@noselasd: storing a database connection resource in the session does not work, so it's moot to speculate if it sped things up or not.
Schnalle
@shore: no, normally pconnect is ok, but there are performance gains only under certain circumstances.
Schnalle
as said,mysql_pconnect will share the same connection between different users,so what if one of them calls the mysql_close to close the connection,while other using that connection to fetch records?
Shore
+6  A: 

Storing a connection in a session just should not work. Don't do that. I'd be surprised if it actually reused that connection on subsequent visits, since it involves networks access, and you can't store a network connection in a file! At best, it reconnects upon the next page view, which doesn't gain you anything. At worst, you have a separate connection for every request that gets held open and not closed properly.

edit - some more thoughts

Furthermore, in the name of optimization, why even bother? Have you actually profiled your code and found this to be the real bottleneck? Just write the code in the most simple and clear way, and then worry about optimization when you discover a real problem that has been measured. Unless you have a very large site, the database connections are not the source of any bottlenecks.

DGM
I'm now trapped in the difference of mysql_connect and mysql_pconnect...
Shore
+8  A: 

Further to DGM's comment, resource types (like a MySQL connection reference) are not restored with a session. The contents of $_SESSION are serialized using serialize() and stored with the session ID, to be restored when the session is started again.

The documentation for serialize states:

string serialize( mixed $value )

value -- The value to be serialized. serialize() handles all types, except the resource type.

This means that you're actually reconnecting with every request. Using mysql_pconnect() as suggested by noselasd would probably alleviate this. Be sure to heed the notes on its manual page, particularly the fact that this requires PHP to run as a module.

Dave
I didn't see how you get the conclusion that "you're actually reconnecting with every request",why serialization will cause reconnect, could you be give more detail?
Shore
serialization creates a textual representation of an object... as PHP is a scripted language (and has no real persistence besides caching, which is really just dumping and reloading variables anyways) there is no way to persist a resource across requests. when the script is done executing, everything is closed.
Jason
The key here is how mysql detects a connection is closed or not.If it each time allocates a unique ID for a new PHP connection,then serialize it in PHP won't close that connection,right?
Shore
`mysql_pconnect()` creates a persistent connection if it can't select one from a pool that it keeps. This pool of available connections lasts the lifetime of the PHP module in the webserver, so if the webserver is restarted (or PHP is not running as a module, but as CGI) then the pool will be emptied, and it will be no different to using `mysql_connect()`. I believe the connections that PHP holds will time out, but I don't know the specifics.
Dave
Any connections made by `mysql_connect()` will create `resource` objects that are released when the script ends, whether they're put into the session or not. A `resource` is a reference to an internal object created by some non-PHP code (e.g. a database connection) which just has an index and a vague "type". PHP doesn't know any more details than that -- it could hold anything. This is why it cannot be serialised and de-serialised. If/when a `resource` is serialised, information is lost because the details only matter to the resource handler (e.g. the MySQL function library)
Dave
The network connection is a network socket held by the OS, and the php connection to mysql is just a reference to that. When that information is serialized, it doesn't keep the OS socket open. Then when you deserialize the info, that reference is no longer valid but it probably just reconnects and re-establishes a connection.If this is not "obvious" to you, then you should not be attempting to optimize anything. I don't know what kind of proof you need. Read the source code to php and the OS.
DGM
A: 

a database connection object is a resource, meaning it's something magical from outside the php world (afaik a c struct or object). you can't serialize a resource, and storing a variable in the session means serializing it (the same thing serialize(); does).

php has a "nothing shared" nature, meaning it shares no resources with other requests. 2 requests may both be from user A, or one user A and one user B, no way to know. every request is encapsulated, and the only very limited "workaround" to make a logical connection between two requests are sessions. everything else must be grabbed from the outside (databases, files, memcached), so it's not php's problem anymore.

because of that, sharing database resources between requests was never meant to be. for every request his own mysql_connect. i assume this was the main reason making mysql popular with the php community in the first place. mysql connects a lot faster than other rdbms, because it had less features (no transactions, no views, no triggers, no nothing), so it was a good fit.

mysql_pconnect did connection pooling (but on a different level), but it wasn't a magic wand either. nowadays you should use PDO anyway (and PDO doesn't support it afaik).

if your application is to slow, the problems lie elsewhere.

my advice:

  • whatever you think you do ... you're not sharing connections, so have a look at that. in fact, your application may be slow because of your trick (if it creates the connection for every query). remove that feature and test again.
  • check your queries (EXPLAIN SELECT * FROM foo;)
  • get your indices right
  • use caching (eg. memcached)

The most common performance problem I see is people who think there's a most-common performance problem that they should be looking for, instead of measuring to find out what their actual performance problem actually is.
- cary millsap

Schnalle
You talk much about it's like this,but little about how it achieves that goal,seems.
Shore
If you want to know how it achieves that goal, ask it as a new question - or study the source code.
nos
A: 

as stated in other answers, php cannot store a resource in text, just cannot be done.

if you are using php 5.3 and mysqli, you can now use persistent connections by prefixing the host param when connecting with "p://".

using the mysql extension, use mysql_pconnect.

you could set up a mysql proxy maybe http://forge.mysql.com/wiki/MySQL_Proxy

Jason
I want only to ask a single question:how many connections will there be after using mysql proxy?
Shore
it really depends on WHY the connections are stacking up in the first place... mysql proxy will reuse connections in a pool (if i remember right). That is the real issue IMO.
Jason
Is there any detailed reference on how mysql proxy is supposed to reuse connections?BTW,if we just use mysql_pconnect,why the connection still exists after execution is done?Isn't PHP supposed to release all resources after done?How the permanant connection is achieved by mysql_pconnect?
Shore
http://forge.mysql.com/wiki/MySQL_Proxy_FAQ, about half way down it mentions the connection pooling capabilities.
Jason
http://www.php.net/manual/en/features.persistent-connections.php
Jason
PDF presentation about mysql proxy, a few slides in it mentions connection pooling http://downloads.mysql.com/forge/slides/MySQL-Proxy.pdf
Jason
but I used mysql_connect to create a connection,then restore it into $_SESSION,then next time when making a call to that page,read that connection from $_SESSION,it still works,say the connection persists even though it's created by mysql_connect?I'm confused...
Shore
without going through and building an example, I would guess that it COULD BE that the serialized db connection is returning some kind of identifier, then your next query call is initiating a reconnect. You may be triggering some kind of bug by storing the resource in session (causing connections to pile up). not sure to tell you the truth :( according to the manual though, you should not be able to do this...... better to go with the suggested methods rather than trigger a bug or cause other issues (you never know, if it is a bug it could be fixed in a new ver of PHP, breaking your code)
Jason
Since connections created by mysql_connect and mysql_pconnect can both persist,the 'p' in mysql_pconnect should not be short for 'persist',but 'proxy',am I right?
Shore
maybe, without looking at PHP's source code for the how, it is hard to say. It is all just terminology really, since php scripts are interpreted without any persistence, persistent connections according to php does translate to being an out of scope proxy in a sense.
Jason