PHP MySQL vs MySQLi Database Access Metrics

Last week I had a MySQL DBA/Developer tell me, “MySQLi sucks” when I asked why some code I was reviewing used the mysql_* extensions provided in PHP instead of mysqli_*. This really didn’t sit well with me. I turned to a trusted source for PHP information, and found they recommend mysqli_* for connecting to MySQL servers versions 4.1.3 and above. Although, I read many anecdotal stories about how mysqli_* was faster, I was unable to find any quantified proof of just how much faster. So in keeping with my performance measurement track I’ve been on this week, I decided to conduct my own test. I was surprised by the result. MySQL is faster in some cases.

The database I used is a pet project of mine that tracks some vehicle information. It uses a varchar primary key based on an automotive VIN number and the sample table I queried against has about 30K rows. The average row length is about 150bytes. I conducted 2 types of tests. The first was a completely unrealistic test measuring how fast a single row could be returned using each of the extension types. The other also returned a random sampling of rows. Since this isn’t a performance test of MySQL, I allowed each test to run one time completely to ensure the query cache was fully populated in MySQL. Then each test was run 3 subsequent times. Each test executed 1,000,000 queries to the server.

Single Hard Coded Query:

The first listing is the mysql_* calls. You’ll notice the

mysql_free_result()

function is commented out. I did test with this enabled and disabled and found that with this function enabled the queries returned at the same rate as with it enabled. So in the interest of fairness, I disabled it to more closely mimic the code executing with the mysqli_* calls.

<?php
	$tq = 1000000;
	$mt = microtime(true);
	$conn = mysql_connect("127.0.0.1","user","");
	mysql_select_db("test_schema", $conn);
	for($i=0; $i<$tq; $i++){
		$data = mysql_query("SELECT * FROM vehicles LIMIT 1", $conn);
		$data_object = mysql_fetch_assoc($data);
		// mysql_free_result($data);
	}
	mysql_close($conn);
	$et = microtime(true) - $mt;
	print "Elapsed time: " . number_format($et) . "s\n";
	print "QPS: " . ($tq / $et) . "\n";
?>

The next listing is the same code converted to leverage the mysqli_* calls. You’ll see that the result is not freed each time through the loop.

<?php
	$tq = 1000000;
	$mt = microtime(true);
	$conn = mysqli_connect("127.0.0.1","user","","test_schema");
	for($i=0; $i<$tq; $i++){
		$data = $conn->query("SELECT * FROM vehicles LIMIT 1");
		$data_obj = $data->fetch_assoc();
	}
	$conn->close();
	$et = microtime(true) - $mt;
	print "Elapsed time: " . number_format($et) . "s\n";
	print "QPS: " . ($tq / $et) . "\n";
?>

The results were surprising to me. The mysql_* extension actually ran considerably faster than the mysqli_* extenstion. In fact, the mysql_* extension ran 3.6% faster. Perhaps this DBA was on to something? I also tested this same methodology using prepared statements with MySQLi and found the results actually degraded. Discouraged, I devised a new test that would hopefully be more realistic. The values provided are queries per second.

Method Run #1 Run #2 Run #3 Avg
mysql_* 7,227.7 7,222.2 7,220.7 7,223.5
mysqli_* 6,963.0 6,974.0 6,974.4 6,970.5
mysqli prepared statements 4,849.6 5,005.3 4,978.7 4,944.5

Parameterized Queries:

More often than not, we do not run the same select query 1 million times, and we are actually more likely to run a query over a series of data sets. While this in itself is a terrible idea in production code because you should re-write the query to do it all as a single database call, it provides a better picture of how the database might be interacted with in PHP; especially if persistent connections are being utilized. However, if you find that you have some code that fits the patterns used here, it might be to your advantage to review the prepared statement code below.

The basic flow of the scripts is to first fetch 10 thousand (~1/3) of the table’s primary keys and populate an array. Then the code will select 1 million rows using a randomly selected primary key (vin). The data is still relatively small, and fits into the query cache after a warm up period. This shows how efficiently the query passing is instead of how efficient MySQL is at answering different questions, making it a better comparison of the two technologies. The three test scripts I ran are provided here for your reference.

Leveraging the mysql_* calls

 
<?php
	print "Fetching VIN array...\n";
	$vin_array = array();
	$conn = mysql_connect("127.0.0.1","user","");
	mysql_select_db("test_schema",$conn);
	$vins = mysql_query("SELECT vin FROM vehicles LIMIT 10000", $conn);
	while($vin = mysql_fetch_assoc($vins)){
		$vin_array[] = $vin['vin'];
	}
	mysql_close($conn);
	unset($conn);
 
	print "Starting test...\n";
	$tq = 1000000;
	$mt = microtime(true);
	$conn = mysql_connect("127.0.0.1","user","");
	mysql_select_db("test_schema", $conn);
	for($i=0; $i<$tq; $i++){
		$data = mysql_query("SELECT * FROM vehicles WHERE vin = '" . $vin_array[rand(0,count($vin_array)-1)] . "'", $conn);
		$data_object = mysql_fetch_assoc($data);
		// mysql_free_result($data);
	}
	mysql_close($conn);
	$et = microtime(true) - $mt;
	print "Elapsed time: " . number_format($et) . "s\n";
	print "QPS: " . ($tq / $et) . "\n";
?>

Leveraging the mysqli_* calls

<?php
	print "Fetching VIN Array...\n";
	$vin_array = array();
	$conn = mysqli_connect("127.0.0.1","user","","test_schema");
	$vins = $conn->query("SELECT vin FROM vehicles LIMIT 10000");
	while($vin = $vins->fetch_assoc()){
		$vin_array[] = $vin['vin'];
	}
	$conn->close();
	unset($conn);
 
	print "Starting test...\n";
	$tq = 1000000;
	$mt = microtime(true);
	$conn = mysqli_connect("127.0.0.1","user","","test_schema");
	for($i=0; $i<$tq; $i++){
		$data = $conn->query("SELECT * FROM vehicles WHERE vin = '" . $vin_array[rand(0,count($vin_array)-1)] . "'");
		$data_obj = $data->fetch_assoc();
	}
	$conn->close();
	$et = microtime(true) - $mt;
	print "Elapsed time: " . number_format($et) . "s\n";
	print "QPS: " . ($tq / $et) . "\n";
?>

Leveraging mysqli_ calls and prepared statements.

<?php
	print "Fetching VIN array...\n";
	$vin_array = array(); 
	$conn = mysqli_connect("127.0.0.1","user","","test_schema");
	$vins = $conn->query("SELECT vin FROM vehicles LIMIT 10000");
	while($vin = $vins->fetch_assoc()){
		$vin_array[] = $vin['vin'];
	}
	$conn->close();
	unset($conn);
 
	print "Running tests...\n";
	$tq = 1000000;
	$mt = microtime(true);
	$conn = mysqli_connect("127.0.0.1","user","","test_schema");
	$stmt = $conn->stmt_init();
	$stmt->prepare("SELECT * FROM vehicles WHERE VIN = ?");
	for($i=0; $i<$tq; $i++){
		$stmt->bind_param("s", $vin_array[rand(0,count($vin_array) - 1)]);
		$stmt->execute();
		$stmt->bind_result($a,$b,$c,$d,$e,$f,$g,$h,$z,$j,$k,$l,$m,$n);
		$stmt->fetch();
	}
	$conn->close();
	$et = microtime(true) - $mt;
	print "Elapsed time: " . number_format($et) . "s\n";
	print "QPS: " . ($tq / $et) . "\n";
?>

The performance of this “harder” task degraded for all technologies. Again, the mysql_* extension was about 3.6% faster, but the prepared statements were 9.7% faster than the old mysql_* calls and 13.7% faster than the mysqli_ calls. This improvement makes a good case for transitioning repetitive calls in your code to prepared statements leveraging the MySQLi extenstions. Again, the values are measured in queries per second.

Method Run #1 Run #2 Run #3 Avg
mysql_* 4,063.6 4,016.7 4,054.0 4,044.8
mysqli_* 3,902.3 3,905.8 3,896.0 3,901.4
mysqli prepared statements 4,443.8 4,421.8 4,445.7 4,437.1

Without testing stored procedures, it’s difficult to say if they would have continued to improve the performance of this test, however, it is clear that the speed advantages of mysqli_* extensions are only present if you are utilizing the advanced features of the more recent versions of the database.

Conclusion:

If your code is purely hard coded statements, the old school MySQL syntax may be your best bet for a performance lift. However, most likely your code would benefit more from prepared statements and some of the other performance enhancements provided by the MySQLi extension set. I wouldn’t say, “MySQLi Sucks” but it does appear there is a valid argument for continuing to use it if you are not leveraging any of the performance enhancements of the newer versions of MySQL.

System Configuration:

  • Mac OS 10.5.6
  • 2.16Ghz Intel Core Duo
  • 2 Gb RAM
  • PHP 5.2.6
  • MySQL Server 5.0.51b
This entry was posted in code, Metrics, MySQL, PHP, SQL and tagged , , , , . Bookmark the permalink.

14 Responses to PHP MySQL vs MySQLi Database Access Metrics

  1. Master says:

    I have information that I know will change your mind. MySQLi does suck. ESPECIALLY with prepared statements. Especially! Prepared statements are almost 3 times SLOWER in real-world every day use. Here’s my proof.

    Yes, prepared statements are faster if you want to perform the exact same query 1 million times within the same connection, and *before* that statement is destroyed and the connection closed. But we both know that’s silly, and only for your demonstration.

    A better test would be 1 million *separate* connections doing the same query. This is what really happens in the real world. One user searches for “red”, another user searches for “red”. Both are separate HTTP requests, separate PHP executions, and both times we’re re-creating the prepared statement from scratch and then destroying it! Even an AJAX search that throws a select query at the database for every keystroke… Even then, with every keystroke, a new HTTP request it sent, a new PHP execution takes place, and the prepared statement is constructed, used, and then destroyed all over again – for every single keystroke!

    My instinct told me this prepared statement crap was slower than simple old fashioned MySQL, so I did a comparison, and I was right. This is the exact working code I used, comparing MySQL to MySQLi with prepared statements:

    //==================================================
    // GOOD OL’ FASHIONED MYSQL
    //==================================================
    $search = ‘red’;

    $link = mysql_connect(‘localhost’, ‘user’, ‘pass’, ‘db’);
    mysql_select_db(‘db’, $link);

    if ($result = mysql_query(“SELECT `Name`, `Type`, `Colour` FROM `Inventory` WHERE `Name` LIKE ‘%$search%’ OR `Type` LIKE ‘%$search%’ OR `Colour` LIKE ‘%$search%’”, $link)) {

    // List it
    while($row = mysql_fetch_array($result)) echo $row['Name'] . ‘    ’ . $row['Type'] . ‘    ’ . $row['Colour'] . ”;

    mysql_free_result($result);
    }

    mysql_close($link);

    //==================================================
    // NEW MYSQLi
    //==================================================
    $search = ‘%red%’;

    $link = mysqli_connect(‘localhost’, ‘user’, ‘pass’, ‘db’);

    // Prepared statement
    if ($preparedStmt = mysqli_prepare($link, ‘SELECT `Name`, `Type`, `Colour` FROM `Inventory` WHERE `Name` LIKE ? OR `Type` LIKE ? OR `Colour` LIKE ?’)) {

    // Prepare variables and execute query
    mysqli_stmt_bind_param($preparedStmt, ‘sss’, $search, $search, $search);
    mysqli_stmt_execute($preparedStmt);
    mysqli_stmt_bind_result($preparedStmt, $name, $type, $colour);

    while (mysqli_stmt_fetch($preparedStmt)) {
    // List it
    echo $name . ‘    ’ . $type . ‘    ’ . $colour . ”;
    }

    mysqli_stmt_close($preparedStmt);
    }

    mysqli_close($link);

    (NOTE: I’ve used procedural as that’s faster than the OO counterpart.)

    I tried each of these separately, running it one at a time by refreshing the browser every time. This is the only fair comparison, because the MySQL connection is destroyed each time. I did 20 tests for each, and recorded all the times. MySQL took 0.0017 on average, whereas MySQLi took 0.0044! Almost 3 times slower every search! You’ll have to add your own time tracker for speed comparisons.

    So in a fair fight, MySQLi looses horribly. And the OO version of MySQLi is even slower still! I won’t even go into that one. ;P

    Please let me know what you think, and if I’ve convinced you.

  2. Erik says:

    I do agree with you that MySQL is faster through mysql_* if you are not leveraging things like stored procedures that simply isn’t supported.

    You’ll notice in my first test I found mysql_* extentions to be roughly 2x faster than prepared statements. It wasn’t until I re-worked the project to do some real work that I saw a significant degradation of mysql_*. You are correct for 1 or 2 queries, prepared statements are slower. Not until you run some queries a few hundred times does it start to make a big difference.

    I whole heartedly disagree with your assumption that the second test is not realistic. If this code is processing a work queue such as one provided by Gearman or SQS, the prepared statement may actually process millions of times before closing the connection. In this scenario – this will account for a significant speed increase in using prepared statements and mysqli_*.

    I also believe when support is added for non-dependent parallel query execution, it will only be added to the mysqli_* extensions. However, I’m not holding my breath for those anytime soon.

    The real lesson here is that it’s important to test assumptions. What works well for my application may not work well for someone else. There’s a right tool for every job and depending on your individual application one will probably work better than the other.

  3. Master says:

    Thanks for the reply.

    Agreed – the right tool for the right Job. My point is that almost all PHP developers will never create a complex queue system from scratch. (To use premade packages like Gearman, one doesn’t even worry about prepared statements). So yes, if you’re creating a sophisticated queuing database system that takes and queues multiple requests at once and then processes them all later, MySQLi’s prepared statements are the way to go. But what average Joe PHP developer even does that, even for a big complex website?

    If you’re the other 99% of PHP developers creating a searchable inventory, member’s login system, content management, blog, AJAX search, or really almost all web 2.0 tasks out there, old fashioned MySQL is faster.

    This is not a point that was made clearly in your article – in fact, you say “most likely your code would benefit more from prepared statements”. I argue most likely it won’t.

  4. GM says:

    Interesting results, but flawed.
    The problem is you have created tests which play to mysql_* strengths and ignore its weaknesses.
    I retried all of your tests and reached much the same results, as I expected to. Only difference was in the number of queries/second for each method and the distance between them was much narrower.
    After that I retried the examples replicating a situation I find myself working with often. Remote database. The Db server is on a separate machine accessed via GigaBit ethernet, a frequent occurrence in shared hosting (although 10/100Mb is more often the case) and not that uncommon in an enterprise situation.
    The results are generally reversed. Test results are:
    Method run 1 run 2 run 3 Mean
    mysql_* (proc) 1618.7 1474.9 1567.2 1553.6
    mysqli_* (proc) 1748.4 1625.6 1806.3 1726.8
    mysqli_* (OOP) 1823.0 1765.2 1675.4 1754.5

    Note the mysqli_* number are for procedural and Object Oriented Paradigm
    Why such a turn around? Apart from remote access is a worse way for mysql_* to work, I used the right methodology for the queries. Your examples are a transliteration of mysql_* to mysqli_* methods. But MySQLi has moved on, it has other ways of skinning these cats now.
    Instead of these two lines:
    $data = $conn->query(“SELECT * FROM vehicles LIMIT 1″);
    $data_obj = $data->fetch_assoc();

    you should use these three:

    $data = $conn->query(“SELECT * FROM vehicles LIMIT 1″, MYSQLI_USE_RESULT);
    $data_obj = $data->fetch_assoc();
    $data->free_result();

    The thing here is; it’s not what you have, but how you use it ;-). The mysql_* extension was written way back when only MySQL 3/4 were really in use. If that’s the kind of database setup you are using then you may never need MySQLi. I do not mean that is the version of MySQL you are still running, but if your databases only use the same functionality as possible on those versions, you will probably never need to upgrade.
    If on the other hand you use newer features, you have no choice but to move on because they simply are not available through mysql_*.

    You might notice I did not do a prepared statement test. I have to agree with ‘Master’, they suck, mostly. But, I would not use client-side prepared statements anyway. Instead I would use server-side prepared statements or stored procedures on the server, neither of which is possible with the legacy API. If you need any other reasons to switch, just look at the additional features available with MySQLi:
    Charsets, server-side Prepared Statements, Stored Procedures, Multiple Statements, complete MySQL 4.1+ functionality.
    These are just the directly available improvements, it does not take into account the additional features that the server can do for you to remove work on the php side (views, triggers, etc), thereby improving the performance of your apps.

  5. Kieran Benton says:

    Hi there I have been trying to follow this debate about mysql vs mysqli and one thing I keep hearing is that there is not PREPARE support for mysql but please correct me if I am wrong cant you simply do

    mysql_query(“PREPARE randomGrabber FROM “SELECT * FROM test WHERE x=? AND y=? AND z=?”);
    mysql_query(‘SET @x=’ . mt_rand(0,50) . ‘, @y=’ . mt_rand(0,50) . ‘, @z=’ . mt_rand(0,50) . ‘;’);
    mysql_query(‘EXECUTE randomGrabber USING @x,@y,@z;’);

    Now to me this looks like a PREPARED query using mysql_query(); yes it’s a bit longer than the mysqli counterpart but I think it does the job.

    I also find doing it with mysql is more portable whereas the mysqli seems to be stuck with in the instance of MySQLi_STMT so for example using mysql

    $mysqlConnection = mysql_connect(‘host’,'username’,'password’);
    mysql_query(‘use database’,$mysqlConnection);
    mysql_query(“PREPARE randomGrabber FROM “SELECT * FROM test WHERE x=? AND y=? AND z=?”);
    mysql_query(‘SET @x=’ . mt_rand(0,50) . ‘, @y=’ . mt_rand(0,50) . ‘, @z=’ . mt_rand(0,50) . ‘;’);
    mysql_query(‘EXECUTE randomGrabber USING @x,@y,@z;’);


    150 lines latter

    mysql_query(‘SET @x=’ . mt_rand(0,50) . ‘, @y=’ . mt_rand(0,50) . ‘, @z=’ . mt_rand(0,50) . ‘;’);
    mysql_query(‘EXECUTE randomGrabber USING @x,@y,@z;’);

    Whereas using the mysqli way you would have to do something like this

    $mysqliConnect = new mysqli(‘host’,'username’,'password’,'database’);
    $stmt = $mysqliConnect->prepare(“SELECT * FROM test WHERE `x`=? AND `y`=? AND `z`=?”);
    $stmt->bind_param(‘iii’,mt_rand(0,50),mt_rand(0,50),mt_rand(0,50));
    $stmt->execute();

    150 lines latter

    $stmt->bind_param(‘iii’,mt_rand(0,50),mt_rand(0,50),mt_rand(0,50));
    $stmt->execute();

    Now those example seem the same but you had to keep the variable $stmt in scope to use thought your intended code and if you wanted to use that prepare somewhere else in your code and it was out of scope you would either have to recreate the prepare statement or somehow make it a global variable (bad idea) or in the instance of a class create a attribute to hold the variable so that it may be used in other methods.

    I have written two example bellow one using mysql and the other using mysqli to show you what I mean about the persistence of both you’ll notice that the mysqli has a fair amount of extra code

    /*
    * MYSQL
    */
    class MySimpleClass {
    protected $connection = null;

    protected $users = array();

    public function __construct($connection){
    mysql_query(‘PREPARE selectUsers FROM “SELECT `userId`,`username`,`firstName`,`lastName` FROM users WHERE `userId` = ?;”‘,$connection);
    mysql_query(‘PREPARE deleteUsers FROM “DELETE FROM users WHERE `username` = ?;”‘,$connection);
    mysql_query(‘PREPARE updateUsers FROM “UPDATE users SET `username` = ? WHERE `userId` = ?;”‘,$connection);
    $this->connection = $connection;
    }

    public function randomStuff(){
    $connection = $this->connection;
    $userIds = mysql_query(‘SELECT `userId` FROM users;’, $connection);
    while($userId = mysql_fetch_assoc($userIds)){
    if(mt_rand(0,1) == 1){
    mysql_query(‘SET @userId = ‘. $userId['userId'] . ‘;’, $connection);
    $user = mysql_query(‘EXECUTE selectUsers USING @userId’, $connection);
    $this->users[] = mysql_fetch_assoc($user);
    }
    }
    }

    public function deleteRandomStuff(){
    $connection = $this->connection;
    foreach($this->users as $user){
    mysql_query(‘SET @userId = ‘ . $user['userId'] . ‘;’, $connection);
    mysql_query(‘EXECUTE deleteUsers USING @userId;’, $connection);
    }
    }

    public function updateRandomStuff(){
    $connection = $this->connection;
    foreach($this->users as $user){
    mysql_query(‘SET @userId = ‘ . $user['userId'] . ‘, @randUsername = ‘ . mt_rand() . ‘;’);
    mysql_query(‘EXECUTE updateUsers USING @randUsername, @userId;’);
    }
    }
    }

    /*
    * MYSQLI
    */
    class MySimpleClassI {
    protected $connection = null;

    protected $selectUsers = null;
    protected $deleteUsers = null;
    protected $updateUsers = null;

    protected $users = array();

    public function __construct(MySQLi $connection){
    $this->selectUsers = $connection->prepare(‘SELECT `userId`,`username`,`firstName`,`lastName` FROM users WHERE `userId` = ?;’);
    $this->deleteUsers = $connection->prepare(‘DELETE FROM users WHERE `username` = ?;’);
    $this->updateUsers = $connection->prepare(‘UPDATE users SET `username` = ? WHERE `userId` = ?;’);
    $this->connection = $connection;
    }

    public function randomStuff(){
    $connection = $this->connection;

    $userIds = $connection->query(‘SELECT `userId` FROM users;’);
    while($user = $userIds->fetch_assoc()){
    if(mt_rand(0,1) == 1){
    $this->selectUsers->bind_param(‘i’,$user['userId']);
    $this->selectUsers->execute();
    $this->selectUsers->bind_result($userId,$username,$firstName,$lastName);
    $this->users[] = array(‘userId’=>$userId,’username’=>$username,’firstName’=>$firstName,’lastName’=>$lastName);
    }
    }
    }

    public function deleteRandomStuff(){
    $connection = $this->connection;
    foreach($this->users as $user){
    $this->deleteUsers->bind_param(‘i’,$user['userId']);
    $this->deleteUsers->execute();
    }
    }

    public function updateRandomStuff(){
    $connection = $this->connection;
    foreach($this->users as $user){
    $this->updateUsers->bind_param(‘is’,$user['userId'],mt_rand());
    $this->updateUsers->execute();
    }
    }

    Theses example show the difference between mysql PREPARE and mysqli PREPARE with mysqli you need to store the prepare query’s in a variable to keep the prepare query alive where in mysql you can simply create the PREPARE statement and refer to it via the name you provided making it president as long as the connection is alive the same cannot be said for mysqli if that variable goes out of scope or just inaccessible then you cannot get access to it.

    There also seems to be allot of overhead to use mysqli which you don’t seem to get with mysql this is very noticeable with mysqli class example I had to create 3 extra attributes to keep the prepare statements accessible inside the method

    If I have this completely gotten this wrong please let me know.

  6. Erik says:

    Kieran,

    Your approach looks interesting. I think it would work so long as the MySQL connection stays active since the variables would reset if the session were to close. Although that may be an issue with the mysqli statement syntax as well – I’m not sure. Have you done any testing to see how the performance measures up?

    BTW: The additional memory reference to keep a prepared statement is rather trivial for modern servers. Additionally, passing the object by reference means there’s only ever the one copy, so I wouldn’t worry about that at all.

    Also, don’t forget to add mysql_real_escape_string() to ensure valid strings which is a baked in feature of the mysqli statements to protect yourself from injection attacks.

    Thanks for sharing your solution.

    Erik

  7. That One Guy says:

    Yes, I am a few months off on this post but please know:
    The mysql extension is no longer under development. That in mind, PHP 5.3.0 is to PHP 5.2.6 as the future mysqli may be to the current. Who says there wont be upgrades in speed and functionality?
    I personally encourage the use of the mysqli extension, as it is still under active development.
    Youre seeming like what a lot of developers dread: a programmer that sticks to older methods when there are new ones being developed that have potential to be a lot faster and more secure if they already arent.
    Expand: Youre stuck on shore because you want to stick by the wave you came in on. Look out into the sea. There are many bigger and better waves coming in. Try riding those.

  8. Erik says:

    That One Guy: You make an excellent point about continued development. I agree with you that it’s time for devs to embrace change and move forward with MySQLi (and object oriented code). However, with many web hosts only supporting MySQL 4.x and some only just recently supporting PHP 5.1, it may be a few years off. The point here was simply to see if there was any validity in the claim about mysqli_* sucking and in some cases, there are clear benefits to using the mysql_* extensions. I personally, won’t be porting my code backward.

  9. Steve says:

    Whew, 25 yrs programmer. New to PHP and starting a pet project. Reading tutorials (excellent Edward Tangueray ~ 5 yrs old (mySQL)) and books from library (a couple of years old (mySQLi). If mySQLi is moving forward and mySQL is stuck then I’m for mySQLi. Thanks guys. Who has a good website or tutorial for melding objects with database?

  10. plokko says:

    You MUST consider that the prepared statement is also sanitizing the input,you should consider it also in the other cases(use mysq_real_escape_string)because most of the mysql query in a website use insecure strings that need checking.

    The process should take a bit of resource so i think the prepared statement does the job well.

  11. Pingback: Anonymous

  12. Thrunobulax says:

    I agree with Master’s comment:

    “If you’re the other 99% of PHP developers creating a searchable inventory, member’s login system, content management, blog, AJAX search, or really almost all web 2.0 tasks out there, old fashioned MySQL is faster.”

    For simple SELECT, UPDATE and INSERT operations, we found mysqli to be significantly slower than it’s mysql predecessor and although I wouldn’t say it “sucks”, we won’t be switching just yet.

  13. Pingback: Which is fastest in PHP- MySQL or MySQLi? - PHP Solution - Developers Q & A

  14. Erik says:

    Just in case anyone doesn’t think mysql_* functions are dead. PHP 5.5 officially deprecates them. See http://us3.php.net/mysql_connect and start migrating your code now.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>