Architecture needed to reduce mysql connections in AJAX/PHP/MYSQL - php

BACKGROUND:
I am passing variables through AJAX to php file. The php file connects to a server and retrieves the result which it passes back to javascript. This happens every time a user clicks on the request button (about every 5 secs). Thus for each user, the php file (and so the mysql connection) is called once every 5 secs.
ISSUE:
As is apparent above, the number of mysql connections are impractically high.
QUESTION:
Is there a better architecture where instead of having so many mysql connections, I can rather have fewer connections.
I have read a little bit about mysql_pconnect. But what happens if I have to upgrade since I read somewhere that mysqli doesnt support it? How many queries can a single mysql_pconnect handle? If anyone suggests mysql_pconnect then how to implement it?

Is there a better architecture where instead of having so many
mysql connections, I can rather have fewer connections.
Don't really know, but I think that for you the proposed pconnect is the best available option. Unless you have either mysqli or PDO_mysql available now?
I have read a little bit about mysql_pconnect.
But what happens if I have to upgrade since I read somewhere that mysqli doesnt support it?
You would probably need to change method when upgrading beyond PHP 5.5.
How many queries can a single mysql_pconnect handle?
Unlimited, as long as the connection is kept alive. If there are no available free connections a new one is created.
If anyone suggests mysql_pconnect then how to implement it?
Change your current mysql_connect calls to mysql_pconnect. That should be all.

What you are looking for is singleton design pattern for database connections. But it has it's trade off too. Example code for singleton design for database would be as below.
define('DB_NAME', "test");
define('DB_USER', "root");
define('DB_PASS', "rootpass");
define('DB_HOST', "localhost");
class Connection{
private static $connection_;
private function __construct(){
$con = mysql_connect(DB_HOST, DB_USER, DB_PASS);
mysql_select_db(DB_NAME, $con);
Connection::$connection_ = $con;
}
public static function getConnection(){
if( !Connection::$connection_ )
new Connection;
return Connection::$connection_;
}
}
$con = Connection::getConnection();
Read more
php singleton database connection, is this code bad practice?
How static vs singleton classes work (databases)
You can find tons of example and information if you google. Hope this helps

Related

The most efficient way to use mysqli connection

I am searching for a efficient way to use PHP MySQL innoDB connection but not able to found conclusive information on the web.
As I know, persistent connection is much faster than non-persistent one,
we can set up the connection in following way:
$instance_mysqli = new mysqli('p:127.0.0.1', 'username', 'password', 'db');
However, from the official website, it said the default behavior is "reset" on reuse, which is slower. http://php.net/manual/en/mysqli.persistconns.php
The mysqli extension does this cleanup by automatically calling the
C-API function mysql_change_user(). The automatic cleanup feature has
advantages and disadvantages though. The advantage is that the
programmer no longer needs to worry about adding cleanup code, as it
is called automatically. However, the disadvantage is that the code
could potentially be a little slower, as the code to perform the
cleanup needs to run each time a connection is returned from the
connection pool.
So, there is no way to pass parameter to the above constructor to avoid "reset"? The only way is to recompile extension from source code as the document suggested?
And my anther question is... if mysqli is so smart that it can automatically reset connection by default, what is the point many people still use non-persistent connection, which is even slower.
The cost of a connection is quite small, whether it is persistent or not, whether there is cleanup or not.
Normally, one should acquire one connection at the beginning of the program, and keep it until the end. (There are some exceptions.)
The only time a connection is really noticeable is if you acquire a connection before each and every SQL query.
Bottom line: Worry about your indexes, system design, etc, not about acquiring the connection.

Already using mysql_connect--should I also use mysqli_connect?

First, some background: I am working on a pre-2000 website that uses mysql_connect and mysql_* functions everywhere. It is not feasible to simply replace all of these at the moment.
I do, however, plan on slowly making the change to mysqli_* functions. I have run into an instance where I need to use mysqli_multi_query though, and was wondering if it would be better to:
Create a function that opens and closes the mysqli connection, while performing one mysqli_multi_query.
Create a function that opens a mysqli connection when needed, and only open the mysqli connection only on pages that need it.
Simply use the mysqli_connect() function the same way I am using the mysql_connect() function and have both connect at the beginning of my scripts and close at the end, on all pages.
The trouble I am having with deciding on these is that 1 limits the number of multi-queries I can do on one page (while also adding to the future code-cleanup that needs to be done), 2 also adds to the code-cleanup, albeit not quite as much as 1, and 3 might be either inefficient, or unsafe, although I would be able to clean-up as I run into the old queries.
This website gets over 1 million visitors per month.
Anyone know what would be "best-practice" in this scenario?
"best practice" seems to be to use PDO for your MySQL connections, according to recent articles turned up during a search on the topic (for example https://phpbestpractices.org/#mysql ) although I couldn't find any specific guidance on when to open those connections if they are not strictly required on that page.
I'd suggest going with your second choice, as the abstraction makes code more manageable and maintainable in the future, for you and for other devs. As far as I know, there is no specific drawback to using mysql_* and mysqli_* functions side-by-side, and it is recommended to use mysqli_* over mysql_* in all cases
( see http://www.php.net/manual/en/mysqlinfo.api.choosing.php, the section under 'recommended API').
However your code will not be as secure as it could be until you complete the transition.
I would say that whether or not to open connections when they are not strictly required is a judgement call for you to make - I'd lean towards only opening it when you need it on general principles of efficiency, however in practice when dealing with legacy code it may prove far more trouble than it's worth. If it doesn't slow your server down too much you could live with it, so long as you recognise it's not the most efficient way to go.
PHP offers three different APIs to connect to MySQL: mysql(outdated), mysqli, and PDO extensions.
You don't need to connect to the database on every request.
mysqli_connect() with p: host prefix
//or
PDO::__construct() with PDO::ATTR_PERSISTENT as a driver option
http://www.php.net/mysql_pconnect
In your case, I would use PDO type connection implemented as the singleton pattern with "permanent" connection options.
Included on top of the every script.
class Database {
private static $instance;
private $dsn = 'mysql:dbname=testdb;host=127.0.0.1';
private $user = 'dbuser';
private $password = 'dbpass';
public static function getInstance() {
if(!self::$instance) {
self::$instance =
new PDO($this->dsn,
$this->user,
$this->password,
array(PDO::ATTR_PERSISTENT)
);
}
return self::$instance;
}
}
That way you can get database instance with:
Database::getInstance();
...and don't flame me for using singletons in the legacy app! ;)

peristent PDO mysql connection alternatives

I currently create a DB connection via PDO for my website like so:
try {
self::$dbh = new PDO("mysql:host={$host};dbname={$dbName}", $dbUser, $dbPass);
self::$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
}
catch (PDOException $e) {
return $e->getMessage();
}
I've been reading about persistent connections so I wanted to add the persistent flag like so:
self::$dbh = new PDO("mysql:host={$host};dbname={$dbName}", $dbUser, $dbPass,
array(PDO::ATTR_PERSISTENT => true
));
From what I've been reading this could be dangerous if something happens mid query etc. It sounds like this isn't really a recommended method.
Are there any other alternatives to maintain a persistent DB connection with MySQL?
The reason to use persistent connections is that you have a high number of PHP requests per second, and you absolutely need every last fraction of a percent of performance.
Even though creating a new MySQL connection is really pretty inexpensive (compared to connecting to Oracle or something), you may be trying to cut down this overhead. Keep in mind, though, that most sites get along just fine without doing this. It depends on how heavy your traffic is. Also, MySQL 5.6 and 5.7 have made it even more efficient to create a new connection, so the overhead is lower already if you upgrade.
The risk described in the post you linked to was that session-specific states didn't get cleaned up as a given DB connection was inherited by a subsequent PHP request.
Examples of session state include:
Unfinished transactions
Temporary tables
User variables
Connection character set
This can even be a security problem, for instance if one PHP user populates a temp table with privileged information, and then another PHP user finds they can read it.
Fortunately, in the 4 years since #Charles gave his answer, the mysqlnd driver has addressed this. It now uses mysql_change_user(), which is like a "soft disconnect" that resets all those session state details, but without releasing the socket. So you can get the benefit of persistent connections without risking leaking session state from one PHP request to another. See http://www.php.net/manual/en/mysqlnd.persist.php
This needs the mysqlnd driver to be enabled, which it should be if you use any reasonably up to date version of PHP.
Why do you need a persistent connection? PHP is stateless and reinitializes every time you make a request, so there is mostly no advantages and quite more disadvantages (i.e. sudden disconnectons with no handlers) in working with a persistent connections.

PHP5 mysqli vs mysql config files

I know this sounds very stupid indeed, but I find mysqli prepared statements and its object-oriented approach attractive so I plan on converting some of my past doodles from mysql to mysqli.
Here it is... The question
In mysql I used to have a configuration file, for example included in every file that needs the database (i.e. require('sys/dbconfig.php');)
I am not sure if I need to do this in mysqli, or do so as others say, open a connection when you need it, close it when you don't need it (i.e. stick $mysqli = new mysqli($host, $user, $pass, $database); everywhere it needs database transactions.
I do it like that:
config.php
define("DB_HOST", "127.0.0.1");
define("DB_NAME", "demo");
define("DB_USER", "root");
define("DB_PASS", "root");
database.php
// include database constants
include_once("config.php");
// create db connection
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
now you can make SQL statements via
$result = $db->query("SELECT x FROM y;");
MySqlI comes in 2 flavours: procedural and object oriented.
When you use the procedural style everything stays the same as in mysqli_.
You are refering to the object oriented style and there the configuration is different .. more object oriented actually. That means that you have to create a new instance of mysqli and use its methods to get the job done.
Note: when using mysqli_ the same way as mysql you will have the same problems with SQL injection. You should use mysqli in combination with prepared queries and parameter binding.
Mysqli opens the connection when it is instantiated with new mysqli(...) (so does PDO).
During a PHP session you should not need to open/close connections to the database because the duration of a PHP session (for normal websites/webapps) is less than 1 second.
Forcing the equivalent of mysql_connect/mysql_close multiple times in the code can be helpful only in long running scripts that do not need an active connection for their entire duration.
The number of separate mysql connections allowed per mysql user is limited depending on the configuration of you server.
If you have some script that runs a long time and that will likely intersect many other scripts, you may use-up all of the allowed connections per user and thus block other users.
I would suggest (as a simple approach) to instantiate mysqli in a file that you will include everywhere you need db access use the variable you stored the mysqli object everywhere you need it using global $db.
I tend to create constants in a config file like Panique does.
I also create an App class with a static method fetch_db that contains the code for the connection. Then whenever I need a db connection I just call App::fetch_db().
I can post the code and a little more explanation later this afternoon when I get home.

using a singleton to connect to MySql on a busy website

I'm wondering if there are any negative performance issues associated with using a Singleton class to connect to MySQL database. In particular I'm worried in the amount of time it will take to obtain a connection when the website is busy. Can the singleton get "bogged down"?
public static function obtain($server=null, $user=null, $pass=null, $database=null){
if (!self::$instance){
self::$instance = new Database($server, $user, $pass, $database);
}
return self::$instance;
}
Even if you write that, each PHP request will still be a different connection. Which is what you want.
You can use a singleton to handle your database connection because even in only one request, your app may send several database queries and you will loose performance if you re-open database connections each time.
But keep in mind that you always have to write clever queries and request your database only for the data you need and as few times as possible. That will make it smooth !
It doesn't really matter from a MySQL performance standpoint whether or not you use singletons in this case as each request to that page will create its own object (singleton or not) and connection.

Categories