Is the PDO Library faster than the native MySQL Functions? - php

I have read several questions regarding this but I fear they may be out of date as newer versions of the PDO libraries have been released since these questions were answered.
I have written a MySQL class that builds queries and escapes parameters, and then returns results based on the query. Currently this class is using the built-in mysql functions.
I am well aware of the advantages of using the PDO Library, e.g. it is compatible with other databases, stored procedures are easier to execute etc... However, what I would like to know is simply; is using the PDO Library faster then using the mysql built-in functions?
I have just written the equivalent class for MsSQL, so rewriting it to work with all databases would not take me long at all. Is it worth it or is the PDO library slower?

I found PDO in many situation/projects to be even faster than the more native modules.
Mainly because many patterns/building blocks in a "PDO-application" require less php script driven code and more code is executed in the compiled extension and there is a speed penalty when doing things in the script. Simple, synthetic tests without data and error handling often do not cover this part, which is why (amongst other problems like e.g. measuring inaccuracies) I think "10000x SELECT x FROM foo took 10ms longer" conclusions are missing the point more often than not .
I can't provide you with solid benchmarks and the outcome depends on how the surrounding application handles the data but even synthetic tests usually only show differences so negligible that you better spend your time on optimizing your queries, the MySQL server, the network, ... instead of worrying about PDO's raw performance. Let alone security and error handling ...

My observation is that PDO seems to be less tolerate of many consecutive connections - that is connections being created in a loop. I know this is bad practice it the first place. When I was using mysql_* my looped queries seemed to be reasonably fast. However when I switched to PDO I noticed much longer response times for these types of queries.
TL;DR; - If you switch to PDO and you call queries in a PHP loop you may need to rewrite the application to call one single query rather than many consecutive queries.

Related

Are mathematical functions in MySQL faster than PHP?

I've been working with MySQL for a while, but I've never really used the supported mathematical functions, such as FLOOR(), SQRT(), CRC32(), etc.
Is it faster / better to use these functions in queries rather than just doing the same on the result set with PHP?
EDIT: I don't think this question is a duplicate of this, as my question is about mathematical functions, listed on the page I linked, not CONCAT() or NOW() or any other function as in that question. Please consider this before flagging.
It is more efficient to do this in PHP.
Faster depends on the machines involved, if you're talking about faster for one user. If you're talking about faster for a million users hitting a website, then it's more efficient to do these calculations in PHP.
The load of a webserver running PHP is very easily distributed over a large number of machines. These machines can run in parallel, handling requests from visitors and fetching necessary information from the database. The database, however, is not easy to run in parallel. Issues such as replication or sharding are complex and can require specialty software and properly organized data to function well. These are expensive solutions compared to adding another PHP installation to a server array.
Because of this, the value of a CPU cycle on the database machine is far more valuable than one on the webserver. So you should perform these math functions on the webserver where CPU cycles are cheaper and significantly more easy to parallelize.
There's no general answer to that. You certainly shouldn't go out of your way to do math in SQL instead of PHP; it really doesn't make that much of a difference, if there is any. However, if you're doing an SQL query anyway, and you have the choice of doing the operation in PHP before you send it to MySQL or in the query itself... it still won't make much of a difference. Oftentimes there will be a logical difference, in terms of when and how often exactly the operation is performed and where it needs to be performed and where the code to do this is best kept for good maintainability and reuse. That should be your first consideration, not performance.
Overall, you have to do some really complex math for any of it to make any difference whatsoever. Some simple math operations are trivial in virtually any language and environment. If in doubt, benchmark your specific case.
Like deceze said there's probably not going to be much difference in speed between using math functions in SQL and PHP. If you're really worried, you should always benchmark both of your use cases.
However, one example that comes to my mind, when is probably better to use SQL math functions than doing PHP math functions: when you don't need to perform any additional operations on the results from the DB. If you do your operations in MySQL, you avoid having to loop through results in PHP.
There is an additional consideration to think of and that's scaling. You usually have one MySQL server (if you have more than one, then you probably already know all of this). But you can have many web servers connecting to the same MySQL server (e.g. when having load balancer).
In that case, it's going to be better to move the computation to the PHP to take the load of MySQL. It's "easier" to add more web servers than to increase the performance of MySQL. In theory you can add infinite amount of web servers, but the amount of memory and the processor speed / num. of cores in a MySQL server is finite. You can scale MySQL in some other ways, like using MySQL cluster or doing master-slave replication and reading from slaves, but that will always be more complicated / harder to do.
MySQL is faster in scope of SQL query. PHP is faster in PHP code. If you make SQL query to find out SQRT() it should be definitely slower (unless PHP is broken) because MySQL parser and networking overhead.

Is PDO really quicker than mysql_* when operating on arrays of data?

Ive recently upgraded my mind from mysql_* to PDO, and I have one simple question:
Is PDO really that much more efficient that the use of a prepared statement and an execute in a for-each loop is quicker than a single call in mysql with multiple values in it?
For example if I have an array of 5 names, putting these in an execute command in a for loop operating on an 'insert' prepared statement - is calling this 5 times going to be quicker in computational speed that one call using the old mysql with all 5 values in a single query? Or is it preferred due to security rather than speed alone?
The meaning and significance of native prepared statements (which you call "PDO") is overlooked and misjudged by everyone.
The speed benefit, everyone talking about so much, in reality can be achieved extremely rare, and often unnoticeable at all. Especially in the area of web-development with PHP which PDO belongs to.
Also note that whatever speed benefit belongs to the query parsing only - no such matters like index rebuilding or time required to find a record to update ever affected by prepared statements.
So, speaking of numbers like five, don't bother yourself with this "once-prepare-multiple execute" thing. It is not what PDO is about. PDO does two essential things, which makes it preferred over two other possible extensions:
it supports prepared statements in general, allowing data in the query not directly but via placeholder. This is the only reason why you should use PDO or similar lib (although you can easily make even old mysql ext to support prepared statements, but PDO offers it out of the box)
it makes such support not as painful as mysqli
Turning back to your question:
You can use either way you like. Just remember that multiple inserts are better to be wrapped in a transaction, due to default settings of the modern DB engines
No matter which way you choose, any dynamical value should be added into query via placeholders only. If you still not convinced, you are welcome to read an article I wrote on the matter (which is still incomplete, but have a through explanation on the real meaning of prepared statements).
PS. There is also one minor benefit of native prepared statements, often forgotten (becaulse seldom demanded) - if native prepared statement were used (and backed by msqlnd driver), the data returned is already formatted according to its type.
One query that fetches 5 rows will probably be quicker than 5 separate calls, so you are comparing apples and oranges.
When executing the same query, the performance will be similar too. The (small) performance advantage that PDO has, is that queries with parameters are supposed to be better cachable. When querying customer 3 and customer 5, the query will be cached as two different queries, while only the id is different. By using parameters, the database might cache the query in a smarter way, so a second call with a different input doesn't need to go through the query optimizer and such.
That said, apart from the performance advantage, PDO is also safer (when actually using paramteres), and in the end easier. It may look more complex at first, but it is easier to do right, because without using parameters, you will need to do all the escaping yourself, risking dangerous bugs.
By the way, you can also build a query with a variable number of parameters, and bind a value to each of them in a loop, so with PDO you could still perform the single insert query for 5 rows, although it will need a bit puzzling and a bit of extra code.

MySQLi Bulk Prepared statements on large site?

I have been digging around stack and all sorts of other sites looking for the best answer to my questions.
I am developing a very large and growing monster of a website, in the form of an information management system. At the core it is running off of PHP and MySQL. I have just updated code, in the more general sense, to mysqli, but without taking full advantage of all of the features. That is part of what I am working on now.
I have read a ton about prepared statements and this is something I certainly need to put to use given the number of statements that get re-used.
I am looking at making in the realm of about 50 prepared statements,
being used across nearly 200 different pages. Is there a recommended
way to do this? All examples I have seen deal with 1 or 2.
Due to the ever growing nature of the site, using databases and such,
one of the things that I liked with the previous mysql is that it
didn't require a connection specified for each query, but does with
mysqli. I had to tweak my functions due to this. Is there a
recommended solution for this?
I built the site in a procedural form rather that object oriented, but I am always open to suggestions, regardless of the format they use.
I'll try to be as accurate as possible, but I'm not an expert.
Your first point: You're probably looking for Stored Procedures. Basically you can store certain logic of your application for repetitive usage.
Prepared Statements, however, are different. They basically mean "Parse once, execute many times" but they're not stored on the server and carried out across connections.
In PHP, each "page load" is a different thread with its own variables and thus its connections to the database, so you cannot really use the Prepared Statement again.
As for your second point, mysql_query() doesn't require a connection handle to be passed to it simply because it assumes you want to use the last created connection.
For example:
mysql_connect();
mysql_query("SELECT * FROM table");
and
$link = mysql_connect();
mysql_query("SELECT * FROM table", $link);
are the same.
So using the connection implicitly doesn't mean scalability.
That's as far as I can write without providing possibly wrong information, so I highly recommend to you really read about this, and then if you have some question everybody here would be happy to answer.

How to add ORM to a PHP legacy project?

We're working on a PHP project, which has been in development for more than 2 years, and now the team is ready and feel the willingness to switch the development on to an ORM. Because it really speeds up the development and allow you to operate by Objects and not think in terms of SQL code and database tables most of the time.
We have decided to choose the Doctrine ORM, because it has YAML data fixtures load - we need it very much for our unit-tests.
The main fear I have, is that using of a new ORM framework can slow the site's performance. We can't make a shared connection between current database abstraction layer (which uses pg_connect syntax, not PDO-compatible). The database connection mechanism can't be switched to PDO-compatible, because there are lots of SQL code incompatible with PDO_SQLITE syntax.
So, as I understand it, if we will start using it, it will double the number of database connections. I'm not sure database server will be able to handle this.
What would you recommend us to do in this circumstance?
Of what relevance is PDO_SQLITE?
Unless you actually plan on using the SQLite driver then compatibility is not mandated by PDO.
If you aren't going to use SQLite then I would make the legacy database layer PDO compatible and re-use the connections until you can fully migrate to Doctrine.
That said, the level of connections is not going to be your only performance concern moving to an ORM. They are inherently inefficient so I'd expect slower queries, higher bandwidth use between application servers and the database servers and higher memory use at the application level due to redundant data inevitably getting selected.
Depending on your current setup, the above may or may not be issues.
You should probably take that last paragraph with a pinch of salt though because they are just traits of ORMs in general and not Doctrine in particular, with which I've had no experience.
The obvious thing you can do is not open a database connection until you need it. I personally use code like this:
public function connect() {
if (!defined('CONNECT')) {
mysql_connect(...);
}
}
public function db_query($query) {
connect();
$ret = mysql_query($query);
if (!$ret) {
die(mysql_error());
error_log(mysql_error() . ' - ' . $query);
}
return $ret;
}
to reduce the amount of repetitive and to only open a connection when you need one.
In your case you then need to break off the smallest chunk you can to begin with. Ideally it should be a vertical slice, meaning this slice will do almost all of its database work with the new code and very little with the old. This way you can minimal doubling up of database connections and this lets you build up some skills and get some experience too.
Beware though, ORM is not by any means a panacea. You may hate SQL and find it fiddly and error prone but you are, for the most part, simply trading one set of problems for another. I personally think that while ORM can be useful it has been overhyped and is more of a false economy than many either realize or are willing to admit. I wrote more on this in Using an ORM or plain SQL?
I'm not saying you shouldn't do it. Just don't go in thinking it'll solve all your problems. Also, since this rewrite won't actually change the functionality at all (from what you've described) I'm not sure if the cost of doing so compares favourably with fixing what's there already. Too many unknowns to say which way your situation will go.
Well, yes and no – your DB connections will only be doubled as long as you have both a non-PDO and a PDO connection.
I'm not sure what you mean with the PDO_SQLITE reference, since SQLite is a wholly different database than the PostgreSQL it seems you're using now.
You should be able to run your current queries through PDO::query just as you do today unless you are doing something very wrong :)

Which is fastest in PHP- MySQL or MySQLi?

I'd like to know if anyone has any first-hand experience with this dichotomy. A few blogs say the mysql extension is faster than mysqli. Is this true?
And I'm only asking about speed. I know mysqli has features that are not present in the older extension.
The MySQL extension is very slightly faster than MySQLi in most benchmarks I've seen reported. The difference is so slight, however, that this should probably not be your criterion for deciding between the two.
Other factors dwarf the difference in performance between mysql and mysqli. Using mod_php or FastCGI, a bytecode cache like APC, or using data caching judiciously to reduce database hits, are far more beneficial for overall performance of PHP scripts than the choice of MySQL extension.
Don't be penny wise and pound foolish! :-)
"It depends."
For example, PHP MySQL vs MySQLi Database Access Metrics and the subsequent comments point out arguments both ways.
If you have a mature database and codebase, do some testing and see what works in your system. If not, stop worrying about premature optimization.
See http://php.net/manual/en/mysqlinfo.api.choosing.php
The overall performance of all three extensions is considered to be about the same. Although the performance of the extension contributes only a fraction of the total run time of a PHP web request. Often, the impact is as low as 0.1%.
According to all the Google results for benchmarks linked by ceejayoz it looks like MySQL is at least slightly faster than MySQLi in all the benchmark tests. I do recommend reading the results for details but just figured I'd post something that directly answered the question and bumps up ceejayoz's answer.
The PHP documentation has a good comparison of mysql, mysqli, and PDO. I know you only asked about speed, but others might find this useful. It talks about the feature differences between the options.
Maybe, this can be a reason to make the right choice :: The Plot to
Kill PHP MySQL Extension
" Yes, you read it right. Recently, Phillip Olson sent to the PHP internals mailing list a proposal to kill the original PHP MySQL extension in future PHP versions. "
In relation to PHP programming language, MySQL is the old database driver, and MySQLi is the Improved driver. MySQLi takes advantage of the newer features of MySQL 5.
Features of MySQLi taken from php.net site:
Object-oriented interface
Support for Prepared Statements
Support for Multiple Statements
Support for Transactions
Enhanced debugging capabilities
Embedded server support
Unless milliseconds matter then don't worry. Surely if you have no need for the extra functionality provided by mysqli then just stick with the tried and tested mysql.
<?php
$start = microtime();
$c = new mysqli('localhost', 'username', 'userpass', 'username_dbname');
$c -> select_db('username_dbname');
$q = $c -> query("SELECT * FROM example");
while ($r = $q -> fetch_array(MYSQLI_ASSOC))
{
echo $r['col1'] . "<br/>\n";
}
$me = $c -> query("SELECT col1 FROM example WHERE id='11'") -> fetch_array(MYSQLI_ASSOC);
echo $me['col1'];
echo (microtime() - $start);
?>
Why when using mysqli oop is there a slight speed increase from using this script with mysql or mysqli procedural style? When testing the above script I get .0009 seconds consistantly more than when using the other 2. When using mysql or mysqli procedural, I loaded the scripts 20x in each different style and the two were always above .001. I load the above script 20x and I get below .001 5x.
MySQLi has two basic advantages over MySQL; prepared statements are a great way to avoid SQL injection attacks. Secondly MySQL (or mariaDB) will do their best to optimize prepared statements and thus you have the potential for speed optimizations there. Speed increases from making the database happy will vastly outsize the tiny difference between MySQL and MySQLi.
If you are feeding in statements you mangle together yourself like SELECT * FROM users WHERE ID=$user_id the database will treat this as a unique statement with each new value of $user_id. But a prepared statement SELECT * FROM users WHERE ID=? stands a much better chance of having some optimizations/caching performed by the database.
But comparisons are fairly moot as MySQL is now officially deprecated. From the horse's mouth:
Deprecated features in PHP 5.5.x
ext/mysql deprecation
The original MySQL extension is now deprecated, and will generate E_DEPRECATED errors when connecting to a database. Instead, use the MySQLi or PDO_MySQL extensions.

Categories