While digging through some old code put together by a former co-worker who's talents I looked up to I noticed after every query they closed the connection the MySQL server.
This seems a bit odd since I've always just closed it at the end of the page and seen most people do the same.
So the question is, is this the best idea in PHP/MySQL? Does it even matter one way or the other? The site this is running on has only about 100 users active on it at any given point throughout the day. So I can't see any real impact it would have one way or the other, but maybe it would make sense for a larger site?
This can be helpful when working on an application that needs to scale to many concurrent users. By doing this, you only have the connection open for as short of a time as possible (ie, only when you are using it).
If you had 500 concurrent requests, they would be able to dovetail better so that one request could be doing computation on the PHP side while another was blocking on the database access.
Closing and opening connections after each query is slower than just use one connection. Maybe closing a connection before a long process is a good idea, so you have few chances to reach the connections limit, but with simple pages your method is, I think, really better.
However, I don't know from how many users you'll start noticing a difference.
Related
I am wanting to hear what others think about this? Currently, I make a mysql database connection inside of a header type file that is then included in the top of every page of my site. I then can run as many queries as I want on that 1 open connection. IF the page is built from 6 files included and there is 15 different mysql queries, then they all would run on this 1 connection.
Now sometimes I see classes that make multiple connections, like 1 for each query.
Is there any benefit of using one method over the other? I think 1 connection is better then multiple but I could be wrong?
Creating connections can be expensive (I don't have a reference for this statement as yet Edit: Aha! Here it is) so it seems as if the consensus is to use fewer connections. Using a single connection for all queries on a single page seems to be a better choice than multiple connections.
In PHP+MySQL usually there is no much sence to use multiple connections per page (just slower and a little more RAM consumed).
The only way it might be useful is when you alter connection paremters which might interfer with other pages (like collation). But good PHP programs usually never do that kind of stuff.
Also, it is a good idea to enable persistent connections, so that 1 MySQL connection would be reused across multiples page executions.
If really depends on the level of activity you suspect the site will generate - if it's a high traffic web site, you'll soon run out of connections (unless you set the adjust MySQLs max connections to a stupidly high level, but that'll eventually grind the server to a halt).
I'd generally recommend that the front end of a web site should use a shared database object (singleton is your friend), as it doesn't require a great deal of discipline to write with this is mind and you won't waste time making connections. If you require additional concurrent queries on the backend, it shouldn't be that much of a deal as this isn't likely to be a highly trafficked area.
Its not recommended to execute multiple small queries where the work can be done using just one query, you can use a single query to get data from multiple tables and ieven multiple databases. see the link below:
http://www.x-developer.com/php-scripts/sql-connecting-multiple-databases-in-a-single-query
I don't see any benefit of using multiple connections, I 'd rather think it is a sign of bad structure. These are the reasons I can think of against using multiple connections:
You have to initialize the database multiple times. Setting conection properties upon connection establishment (like SET NAMES UTF8) would have to be done on multiple line.
It is definitely slower than a single connection.
A non-technical reason: Someone working with your code will most probably not expect it and might spend hours debugging the connection properties he had set in another connection.
Having a global connection object (or a class providing one) is the much better approach in PHP.
Are you sure the classes that make multiple connections aren't just returning a reference to the already open connection when one is open? I've seen a lot of stuff structured that way. It really is better performance-wise to use only one connection per page.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Just curious how other people feel about this. Will appreciate opinions or facts, whatever you got :)
I am working on an application where a lot of info is pulled from MySQL and needed on multiple pages.
Would it make more sense to...
Pull all data ONCE and store it in SESSION variables to use on other pages
Pull the data from the database on each new page that needs it
I assume the preferred method is #1, but maybe there is some downside to using SESSION variables "too much"?
Side question that's kind of related: As far as URLs, is it preferable to have data stored in them (i.e. domain.com/somepage.php?somedata=something&otherdata=thisdata) or use SESSION variables to store that data so the URLs can stay general/clean (i.e. domain.com/somepage.php)?
Both are probably loaded questions but any possible insight would be appreciated.
Thanks!
Your question can't be answered to the point where the answer is applicable everywhere.
Here's why: many web server architectures deal with having HTTP server (Apache, Nginx), serverside language (PHP, Ruby, Python) and RDBMS (MySQL, PostgreSQL) on one and the same machine.
That's one of the most common setups you can find.
Now, this is what happens in your scenario:
You connect to MySQL - you establish a connection from PHP > MySQL and that "costs" a little
You request the data, so MySQL reads it from the hard drive (unless cached in RAM)
PHP gets the data and allocates some memory to hold the information
Now you save that to a session. But by default, sessions are disk based so you just issued a write operation and you spent at least 1 I/O operation of your hard drive
But let's look at what happened - you moved some data from disk (MySQL) to RAM (PHP variable) which then gets saved at disk again.
You really didn't help yourself or your system in that case, what happens is that you made things slower.
On the other hand, PHP (and other languages) are capable of maintaining connections to MySQL (and other databases) so they minimize the cost of opening a new connection (which is really inexpensive in the grand scheme of things).
As you can see, this is one scenario. There's a scenario where you have your HTTP server on a dedicated machine, PHP on dedicated machine and MySQL on dedicated machine. The question is, again, is it cheaper to move data from MySQL to a PHP session. Is that session disk based, redis based, memcache based, database based? What's the cost of establishing the connection to MySQL?
What you need to ask, in any scenario that you can imagine - what are you trading off and for what?
So, if you are running the most common setup (PHP and your database on the same machine) - the answer is NO, it's not better to store some MySQL data in a session.
If you use InnoDB (and you probably are) and if it's optimized properly, saving some data to a session to avoid apparent overhead of querying the db for reads won't yield benefits. It's most likely going to be quite the opposite.
Putting it into the session is almost always a terrible idea. It's not even worth considering unless you've exhausted all other options.
Here's how you tackle these problems:
Evaluate if there's anything you can do to simplify the query you're running, like trim down on the columns you fetch. Instead of SELECT * try SELECT x,y where those are the only columns you need.
Use EXPLAIN to find out why the query is taking so long. Look for any easy wins like adding indexes.
Check that your MySQL server is properly tuned. The default configuration is terrible and some simple one-line fixes can boost performance dramatically.
If, and only if, you've tried all these things and you can't squeeze out any more performance, you want to try and cache the results.
You only pull the pin on caching because caching is one of the hardest things to get right.
You can use something like Memcached or Redis act as a faster store for pre-refetched results. They're designed to automatically expire cached data that's no longer used.
The reason using $_SESSION is a bad idea is because once data is put in there very few take the time to properly expunge it later, leading to an ever growing session. If you're concerned about performance, keep your sessions as small as possible.
Just think about your users(client pc). session takes some spaces to user pc, also session can get lost, may e after closing page, or copying the link and paste it to other browser. God practice there i think just use query, but note something, try as much as possible to reduce number of queries in page, it will slow down your site.
I was always in assumption that it is always a good practice to close database connection, regardless of database/ORM, like mysql_close(), Propel::close() etc.
With reference to one of my other question and some other research on Internet, I came to know a surprising face that most people recommends it doesn't really matter if you close connection as connection always gets closed after the request.
However I'm finding those answers little difficult to digest. Reason is, why all DB lib, ORM provide close method? If it is there, in every ORM/lib, there must be some good use of it.
Can someone please shed some light on under what circumstances, we should use close method to close DB connection? & if these methods are not useful at all, why they are present there in all db libs/ORM?
EDIT
My Conclusion
It was a good discussion between Bondye and Fluffeh and it cleared my doubts about use of connection closing. Thanks to both of them.
If your script is expected to last of less than 100 ms, dont bother closing connection.
BUT: if script is expected to last longer and there is some time between last DB operation and close of script, free connection for others by calling *close().
It is really very difficult for me to accept one answer as both answer are correct on its place. Just accepting answer with all comments so that it remain on top. But +1 to both correct answers.
Using mysql_close() isn't usually necessary, as non-persistent open links are automatically closed at the end of the script's execution.
Freeing resources
Thanks to the reference-counting system introduced with PHP 4's Zend Engine, a resource with no more references to it is detected automatically, and it is freed by the garbage collector. For this reason, it is rarely necessary to free the memory manually.
Hope this helps you more.
(source)
edit:
The purpose of mysql_close() is also to save computer resources, but another key reason for using it is because there is a limited number of connections that a MySQL server can accept, and if you have several clients holding connections open for no reason then the server may well need to turn away other, waiting clients. Naturally this is a bad thing, so, as with mysql_free_result(), it is good to call mysql_close() if you think there will be some time between your last database use and your script ending.
It is always good practice to close a database connection when you no longer need it. Even if it gets closed automatically after the script ends - that might be another second or a number of split seconds later. If you no longer need it, one user hitting a page and wasting the database connection for half a second won't make a difference - but twenty doing it at once is suddenly 10 seconds of open connection - and that does make a difference.
At the same time, re-using a connection can be a good practise - making and opening the connection normally takes at least a few milliseconds - and if you are for example inserting a few hundred thousand rows, that few milliseconds each time adds up really fast.
In a way, it is no different to setting a variable to NULL or unsetting it. You don't have to do it, but clean elegant code and resource management is always a good thing.
Database connections are not unlimited. Commercial database software, especially, often have licenses that limit the number of simultaneous connections to a relatively small number. In such a situation, you definitely want to close the connection when your script is no longer actively using. While PHP does automatically close database connection when a script terminates, it doesn't do so until the visitor has finished downloading the page. If his connection is slow (dial-up or mobile), that could take ten, twenty seconds for all you know.
Well developed ORM's like Doctrine and Propel are good at closing MySQL connections. But if you are using straight php, I've seen a lot of database problems tracked back to unclosed connections. It's wise to close all db connections at the end of each script.
Right now the setup for my javascript chat works so it's like
function getNewMessage()
{
//code would go here to get new messages
getNewMessages();
}
getNewMessages();
And within the function I would use JQuery to make a get post to retrieve the messages from a php scrip which would
1. Start SQL connection
2. Validate that it's a legit user through SQL
3. retrieve only new message since the last user visit
4. close SQL
This works great and the chat works perfectly. My concern is that this is opening and closing a LOT of SQL connections. It's quite fast, but I'd like to make a small javascript multiplayer game now, and transferring user coordinates as well as the tens of other variables 3 times a second in which I'm opening and closing the sql connection each time and pulling information from numerous tables each time might not be efficient enough to run smoothly, and might be too much strain on the server too.
Is there any better more efficient way of communicating all these variables that I should know about which isn't so hard on my server/database?
Don't use persistent connections unless it's the only solution available to you!
When MySQL detects the connection has been dropped, any temporary tables are dropped, any active transaction is rolled back, and any locked tables are unlocked. Persistent connections only drop when the Apache child exits, not when your script ends, even if the script crashes! You could inherit a connection in the middle of a transaction. Worse, other requests could block, waiting for those tables to unlock, which may take quite a long time.
Unless you have measured how long it takes to connect and identified it as a very large percentage of your script's run time, you should not consider using persistent connections. In fact, that should be what you do here, if you're worried about performance. Check out xhprof or xdebug, profile your code, then start optimizing.
Maybe try to use a different approach to get the new messages from the server: Comet.
Using this technique you do not have to open that much new connections.
http://www.php.net/manual/en/features.persistent-connections.php
and
http://www.php.net/manual/en/function.mysql-pconnect.php
A couple of dozen players at the same time won't hurt the database or cause noticeable lag if you have efficient SQL statements. Likely your database will be hosted on the same server or at least the same network as your game or site, so no worries. If your DB happens to be hosted on a separate server running an 8-bit 16mz board loaded with MSDOS, located in the remote Amazon, connected by radio waves hooked up to a crank-powered generator operatated by a drunk monkey, you're on your own with this one.
Otherwise, really you should be more worried about exactly how much data you're passing back and forth to your players. If you're passing back and forth coordinates for all objects in an entire world, page load could take a painfully long time, even though the DB query takes a fraction of a second. This is sometimes overcome in games by a "fog of war" feature which doesn't bother notifying the user of every single object in the entire map, only those which are in immediate range of the player. This can easily be done with a single SQL query where object coordinates are in proximity to a player. Though, if you have a stingy host, they will care about the number of connects and queries.
If you're concerned about attracting even more players than that, consider exploring cache methods like pre-building short files storing commonly fetched records or values using fopen(), fgets(), fclose(), etc. Or, use php extensions like apc to store values in memory which persist from page load to page load. memcache or memcached also act similarly, but in a way which acts like a separate server you can connect to, store values which can be shared with other page hits, and query.
To update cached pages or values when you think they might become stale, you can run a cron job every so often to update these files or values. If your host doesn't allow cron jobs, consider making your guests do that legwork: a line of script on a certain page will refresh the cache with new values from a database query after a certain number of page hits. Or cache a date value to check against on every page hit, and if so much time has passed, refresh the cache.
Again, unless you're under the oppressive thumb of a stingy host, or unless you're getting a hundred or more page hits at a time, no need to even be concerned about your database. Databases are not that fragile. If they crashed in a hysterical fit of tears anytime more than one query came their way, the engineers who made it wouldn't have a job for very long.
I know this is quite an annoying "answer" but perhaps you should be thinking about this a different way, after all this is really not the strongest use of a relational database. Have you considered an XMPP solution? IMO this would be the best tool for the job and both ejabberd and openfire are trivial to set up these days. The excellent Strophe library can make the front end story easy, and as an added bonus you get HTTP binding (like commet) so you won't need to poll the server, your latency will go down and you'll be generating less HTTP traffic.
I know it's highly unlikely you're going to change your whole approach just cos I said so, but wanted to provide an alternative perspective.
http://www.ejabberd.im/
http://code.stanziq.com/strophe/
Specifically, I have a DB class that opens and closes multiple MySQL connections every time I call the Query function in the class. Should I open a connection once? or is it ok to open and close connections like this?
My simple-minded (ISAM, no transactions) C-language app runs for eight hours a day, updating multiple tables in one database over one single MySQL connection that stays open the whole time. It works just fine. Anytime there's any kind of MySQL error (not only server gone away), the code just calls mysql_real_connect() again and it picks right up without any trouble. Reconnection is one of the places where, in my opinion, MySQL functions flawlessly.
But there's plenty of controversy and discussion about the goodness/badness of persistent connections. You can find some of it here:
http://www.google.com/webhp?hl=&sourceid=navclient-ff&rlz=1B3GGLL_enUS384US384&ie=UTF-8#rlz=1B3GGLL_enUS384US384&hl=en&source=hp&q=mysql+persistent+connection&aq=0&aqi=g4g-m5&aql=&oq=mysql+persistent+conn&gs_rfai=Ch2c6iCchTO3zG4i6MZ-i7JAOAAAAqgQFT9BAKCs&fp=ff274912d96214e6
-- HTH
If you don't want to change much instead of mysql_connect() use mysql_pconnect()
This way you will use the opened connection. Bu I would agree with #Sarfraz Ahmed - use it only once
Should I open a connection once?
No.
I thought it would be better to release the memory
Actually, connect itself do not consume memory.
And - most important part - you should not worry of such imaginable things.
Don't make decisions on based on empty assumptions.
Here is 2 simple rules to follow:
When you don't know, what to do, do it most general way, as everyone does.
Do necessary things only. Don't try to foresee every problem in the future. Deal only with present problems, not with imaginable ones. Premature optimization is the root of all evil, as it said.
Should I open a connection once? or is
it ok to open and close connections
like this?
You should open multiple connection only when needed otherwise it is not a good idea to open multiple connections thereby consuming a lot of memory which is an overhead.
In general, go back to the simplest MySQL tutorial you can find and do it just that way. Don't deviate unless you have a problem you are trying to solve.
MySQL works just fine when you keep it brain-dead simple. Don't add complexity.
BTW, are you writing yet another MySQL abstraction layer? Why? This question is a good example why reinventing a wheel can be risky.
conecting also uses cpu time. so if you reconnect about 8 times per page, and you have somewhat about 100 visitors a day wich call up 5 pages in average you have 8*100*5=4000 reconnects in one day. and thats a small website. you should realy think about connecting only once or when the connection is getting lost. that would somehow lower your electricity bill also ;-)
I think you should use a Registry Object to open your Database Connection, and make your Database Object a singleton.
Registry::Set('DB', new Database());
$DB = Registry::Get('DB');