In my PHP program I need to hit the database between 0 and 3 times on any given webpage request. I am using PDO to interact with MySQL. First I create a database connection using something like this:
$dbh = new PDO("mysql:host=$hostname;dbname=animals", $username, $password);
Then I do what I need to do and close the connection like this:
$dbh = null;
I open and close a connection 0-3 times right now, the same number of times I need to interact with MySQL.
My question is, should I be re-using this connection instead? My queries are not one after another, they are scattered throughout my program and I don't really think it would be easy to run them one right after another.
So is it better to create a new database connection and close it for each interaction (query) or to just leave the connection open and reuse it? Does it make any difference?
Thanks!
For a typical website page, you should be reusing the same connection for all queries.
It's not worth it to spend time disconnecting and reconnecting.
Unless your pages take a huge amount of time to run (huge being relative), then there's no point in relinquishing a connection. You'll end up wasting more cycles on connectiong/disconnecting than you do actually executing queries. MySQL's pretty lightweight as far as connections go, but it still adds up.
The site says: "You must have 50 reputations to comment". My reputation is pretty bad so I can't leave a comment, but I want to add a notice on:
For a typical website page, you should be reusing the same connection
for all queries.
Absolutely right, but in case of need atypical script (e.g. compare tables between a remote database and local database) one can't use the same connection. Must close first connection and establish new one or have 2 separate connections (using different names) at the same time.
I prefer the second option in this case because of closing connection using "$dbh = null;" it can be a bit difficult in some cases. (PDO closing connection)
Here is explanation [from documentation: https://www.php.net/manual/en/pdo.connections.php ] why should be careful with "$dbh = null;" (it should be closed all instances too):
<?php
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
// use the connection here
$sth = $dbh->query('SELECT * FROM foo');
// and now we're done; close it
$sth = null;
$dbh = null;
?>
So, only $dbh = null; (without nullifying instances) is not a good idea.
Related
This is my first time asking a question on here. I've scoured Google, stackoverflow, etc. looking for help with the issue I'm having. We're currently using PHP 5.3.10 & MySQL 5.0.95 with Apache 2.2.21 (CentOS).
We're in the process of starting to cut over from the old mysql library to mysqli in new code, and I'm leading the charge. I've tried
making sure I explicitly close the connection to the database when I'm done with it
freeing result sets when I'm done with them
upping the connection limit to 250 from 150
There are included files (having to do with session checking, etc.) that use the old style mysql_pconnect() to validate certain things. These are included in nearly all of our code.
something like the code:
$mysqli = new mysqli('p:'.DBHOST, DBUSER, DBPASS, $_SESSION['dbname']);
if ($mysqli->connect_error) {
throw new Exception($mysqli->connect_error, $mysqli->connect_errno);
exit;
}
// do my stuff here, a bunch of SQL queries like:
$sql = 'SELECT * FROM MyTable';
$result = $mysqli->query($sql);
if (!$result) {
throw new SQLException($sql, $mysqli);
exit;
// SQLException is an extension to mysqli_sql_exception that adds the
// query into the messaging internally
}
while ($result && $row = $result->fetch_assoc()) {
// do stuff here, like show it on screen, etc., all works normally
}
$result->free(); // free up the result
$mysqli->close(); // close the connection to the database
freeing the results and closing the connection were things I did after getting a "Too many connections" error. Before doing that, I would get 3-4 new database connections each time I ran my program. (viewed in the back end with SHOW PROCESSLIST)
The problem is lessened somewhat (it adds 0 to 3 new connections, rather than 3 new connections each time).
Some of my reading suggests that this could have something to do with Apache threading + the new persistent connections added if there are no existing idle ones in the current thread. Is it this? Are persistent connections not supported well with mysqli? (should I give up on persistence?)
Thanks for any suggestions you might have.
I have no experience with mysqli persistent connections but some of your questions and expectations looks strange to me.
mysqli opens multiple new processes with p: connect option
Yes, that's what permanent connections are for
making sure I explicitly close the connection to the database when I'm done with it
You cannot make sure you closed it explicitly as you just can't do that. Again because the only point of permanent connection is to lasts open
I would get 3-4 new database connections each time I ran my program.
So, you have to make sure you're opening only one.
You have at least two connects from your script - one old style and some from mysqli?
How many mysqli objects being instantiated?
How many php scripts being run to serve one HTTP request? Are you sure?
After all, if it bothers you so much, why you're using persistent connections? Are you any real (not imaginary) benefits from it?
After all, if your version is 5.3, why bother with rewriting from mysql at all?
I'm a fairly new php programmer. I've been learning for several weeks and over those weeks i've tinkered from hello world scripts to taking other scripts online and installing them and modifying them. Now i'm writing my own and in the course of writing it, I had a bit of an epiphany.. because the scripts ive been modifying and toying with were done a certain way so i started that way as well. But now im thinking it could be inefficient coding or my idea is just wrong for some reason however..
my script is say index.php it's an interactive site and has users. i have 4 different databases that store some form of data. the first database is focused on users and their data. the second on something else, and so on.
The way I have been writing it is that anytime i need to do a query to the database, at the beginning of the script i have my database connection variables all defined such as
$servername = "127.0.0.1";
$dbusername = "dbusername";
$dbpassword = "passwordhere";
$dbname = "database1";
$roomdb = "database2";
etc
etc
so at all sorts of different points in my script there are needs to run database queries so i've been opening a connection like so
$link = mysqli_connect("$servername", "$dbusername", "$dbpassword", "$roomdb");
then running the query
then closing the database connection.
But then i was having a shower and thought suddenly.. why can't i just at the top of my script where i define the database connection info, just open ONE connection to each of the databases. then run the entire script, and just use queries where i need to use them.. and just name the queries differently if i need to have multiple queries to one database. like $query1 , $query2 etc where a query would be like
$query = "INSERT INTO `$room` (room, message, color) VALUES ('$room', '$randomvariable', '$randomvariable')";
does this make sense? it just seems to me that if i almost assuredly have to make multiple connections to each of these databases each time the script is run, and even if theres a chance i dont need one of the connections once in a while, that it would be more efficient to just connect it once at the beginning, have it available then use unique query names for each different query, and then close the connections at the end of the script?
any insights as to why i might be wrong or why it might be better to open the full connection right where you need it then close it again would be appreciated. i want to know how it functions best so i can make the best coding practice as possible....
but lets pretend i even have one database. the same logic applies. is it more efficient to just open one db connection at the top of my script, keep it open the whole run of the script and just use different $querynames to execute queries to the same db rather than open it, run query, close it, and do that 10 different times for all the queries. it seems pointless to me to open and close the connection so many times and adding overhead. did the examples i learn from just code bad or is there a reason for that
We need to save each connection handler in different variable
$link1 = mysqli_connect("$servername", "$dbusername", "$dbpassword", "$roomdb");
$link2 = mysqli_connect("$servername", "$dbusername", "$dbpassword", "$dbname");
Then use the $link_identifier separately for each, so that we know what are connecting to
mysqli_query($link1,"INSERT INTO `$room` (room, message, color) VALUES ('$room', '$randomvariable', '$randomvariable'");
mysqli_close($link1);
Note : Opening a connection for too long is not good coding standard. We would only connect when we are needed to query anything in that database, and close the connection immediately after the transaction is over.
This is my first time asking a question on here. I've scoured Google, stackoverflow, etc. looking for help with the issue I'm having. We're currently using PHP 5.3.10 & MySQL 5.0.95 with Apache 2.2.21 (CentOS).
We're in the process of starting to cut over from the old mysql library to mysqli in new code, and I'm leading the charge. I've tried
making sure I explicitly close the connection to the database when I'm done with it
freeing result sets when I'm done with them
upping the connection limit to 250 from 150
There are included files (having to do with session checking, etc.) that use the old style mysql_pconnect() to validate certain things. These are included in nearly all of our code.
something like the code:
$mysqli = new mysqli('p:'.DBHOST, DBUSER, DBPASS, $_SESSION['dbname']);
if ($mysqli->connect_error) {
throw new Exception($mysqli->connect_error, $mysqli->connect_errno);
exit;
}
// do my stuff here, a bunch of SQL queries like:
$sql = 'SELECT * FROM MyTable';
$result = $mysqli->query($sql);
if (!$result) {
throw new SQLException($sql, $mysqli);
exit;
// SQLException is an extension to mysqli_sql_exception that adds the
// query into the messaging internally
}
while ($result && $row = $result->fetch_assoc()) {
// do stuff here, like show it on screen, etc., all works normally
}
$result->free(); // free up the result
$mysqli->close(); // close the connection to the database
freeing the results and closing the connection were things I did after getting a "Too many connections" error. Before doing that, I would get 3-4 new database connections each time I ran my program. (viewed in the back end with SHOW PROCESSLIST)
The problem is lessened somewhat (it adds 0 to 3 new connections, rather than 3 new connections each time).
Some of my reading suggests that this could have something to do with Apache threading + the new persistent connections added if there are no existing idle ones in the current thread. Is it this? Are persistent connections not supported well with mysqli? (should I give up on persistence?)
Thanks for any suggestions you might have.
I have no experience with mysqli persistent connections but some of your questions and expectations looks strange to me.
mysqli opens multiple new processes with p: connect option
Yes, that's what permanent connections are for
making sure I explicitly close the connection to the database when I'm done with it
You cannot make sure you closed it explicitly as you just can't do that. Again because the only point of permanent connection is to lasts open
I would get 3-4 new database connections each time I ran my program.
So, you have to make sure you're opening only one.
You have at least two connects from your script - one old style and some from mysqli?
How many mysqli objects being instantiated?
How many php scripts being run to serve one HTTP request? Are you sure?
After all, if it bothers you so much, why you're using persistent connections? Are you any real (not imaginary) benefits from it?
After all, if your version is 5.3, why bother with rewriting from mysql at all?
This question already has answers here:
"Commands out of sync; you can't run this command now" - Caused by mysqli::multi_query
(3 answers)
Closed 7 months ago.
I am currently doing the following:
$mysqli = new mysqli($server, $username, $password, $database);
$mysqli->multi_query($multiUpdates);
while ($mysqli->next_result()) {;} // Flushing results of multi_queries
$mysqli->query($sqlInserts);
Is there a faster way to dump the results?
I do not need them and just want to run the next query however I get the error:
Commands out of sync; you can't run this command now
Problem is the while ($mysqli->next_result()) {;} takes about 2 seconds which is a waste for something I don't want.
Any better solutions out there?
Found a faster solution which saves about 2-3 seconds when updating 500 records and inserting 500 records.
function newSQL() {
global $server, $username, $password, $database;
$con = new mysqli($server, $username, $password, $database);
return $con;
}
$mysqli = newSQL();
$mysqli->multi_query($multiUpdates);
$mysqli->close();
$mysqli = newSQL();
$mysqli->query($sqlInserts);
$mysqli->close();
Not sure how practical it is but works well for speed.
If closing and reopening the connection works for you, then you might be better off changing the order:
$mysqli = newSQL();
$mysqli->query($sqlInserts);
$mysqli->multi_query($multiUpdates);
$mysqli->close();
If you don't care which runs first, the query runs more predictably. As soon as it finishes, MySQL will return the results of the insert statement to the PHP client (probably mysqlnd). The connection will then be clear and can accept the next request. No need to close and reopen after a query. So you save the time it takes to close and reopen the connection with this order.
The multi_query is more complicated. It returns the results of the first update before the PHP code continues. At this point, we don't know if the later updates have run or not. The database won't accept any more queries on this connection until it has finished with the multi_query, including passing the results back with next_result. So what happens when you close the query?
One possibility is that it blocks until the multi_query is finished but does not require the results. So closing the connection essentially skips the part where the database server returns the results but still has to wait for them to be generated. Another possibility is that the connection closes immediately and the database continues with the query (this is definitely what happens if the connection is simply dropped without formally closing it, as the database server won't know that the connection is broken until it finishes or times out, see here or here).
You'll sometimes see the claim that query and multi_query take the same time. This is not true. Under some circumstances, multi_query can be slower. Note that with a normal query (using the default MYSQLI_STORE_RESULT), the database can simply return the result as soon as it finishes. But with multi_query (or with MYSQLI_USE_RESULT), it has to retain the result on the database server. If the database server stores the result, it may have to page it out of memory or it may deliberately store the result on disk. Either way, it frees up the memory but puts the result in a state where it takes more time to access (because disk is slower than memory).
NOTE for other readers: multi_query is harder to use safely than query. If you don't really know what you are doing, you are probably better off using PDO than mysqli (because PDO does more of the work for you) and you are almost certainly better off doing your queries one at a time. You should only use multi_query if you understand why it increases the risk of SQL injections and are avoiding it. Further, one usually doesn't need it.
The only real advantage to multi_query is it allows you to do your queries in one block. If you already have queries in a block (e.g. from a database backup), this might make sense. But it generally doesn't make sense to aggregate separate queries into a block so as to use multi_query. It might make more sense to use INSERT ON DUPLICATE KEY UPDATE to update multiple rows in one statement. Of course, that trick won't work unless your updates have a unique key. But if you do, you might be able to combine both the inserts and the updates into a single statement that you can run via query.
If you really need more speed, consider using something other than PHP. PHP produces HTML in response to web requests. But if you don't need HTML/web requests and just want to manipulate a database, any shell language will likely be more performant. And certainly multithreaded languages with connection pools will give you more options.
My application will be hosted in a shared hosting provider with a limit of 25 Mysql concurrent connections. Below is my code for connecting to DB
function dbConnect() {
$dbHost = 'localhost';
$dbUser = 'user';
$dbPass = 'pass';
$dbName = 'dbase';
mysql_connect($dbHost, $dbUser, $dbPass)or die(mysql_error());
mysql_select_db($dbName) or die(mysql_error());
}
My application is more on database query. The home page alone has atleast 20 mysq_query in it. The way I code my home page is like below
include 'config.php';
dbConnect();
query1 ... //to get initial variables
process variables that result in multiple query
query2... // process result
query3...// process result
and so on up to....
query 20...// process result
I cant minimize the query anymore coz most of the query is prerequisite of the other query. I am expecting of at least 1000 users daily, and the possibility of 50% of the users will connect on the same time or at lest seconds apart.
On the design of connecting to DB will I easily reach the connection limit set?
Is php closing the connection right after the query, meaning it closes after the first query, then open on the second and closes again right after, and so on and son, even if I'm not closing the connection myself
Is my assumption correct that the above scenario automatically consumed 20 concurrent connections?
Thanks in advance.
For what it's worth, some answers to questions 2. and 3. of genpet's original post:
PHP closes your connection to MySQL if and only if (assuming it wasn't openned with mysql_pconnect()):
you call mysql_close()
you reach the end of the script
Therefore, if you send 20 queries during the same script, you only consume 1 connection
One thought just comes to my mind. Consider this pattern:
open/poll a connection with *_pconnect()
run a query, deal with the results
release the connection ASAP with *_close()
open/poll again if you need to query the DB later in the script
This way, I believe one could work around the low concurrent connections limit (even though I agree with people advising your hosting plan may be inappropriate to fulfill your needs)
This is theory, though, I haven't tried that in the real.
It won't let me post this as an comment above, so this isn't an answer, but an extension of my first comment ("upgrade your hosting plan")
IMO, your connection design is not ok. "die" is a terminal function, if you're expecting failure, then build in a retry option and a user friendly error handling function. Also, opening and closing the DB each time is time intensive, you might be able to squeeze three queries faster than closing down and opening again for one (but that depends on several factors, which can be mitigated worth shared pools add suggested by others.) But my advice is upgrade hosting plan and develop "normally". Then your style is ok, except use a friendlier error screen than "die" :-) as well as pdo or mysqli, not mysql_ functions