3. Overview of the MySQL PHP drivers/connectors/API ¶
There are several PHP APIs for accessing
the MySQL database.
Users can choose between mysqli, PDO_MySQL, or X DevAPI
All three use mysqlnd driver
4. Overview of the MySQL PHP drivers/connectors/API ¶
There are several PHP APIs for accessing
the MySQL database.
Users can choose between the mysqli, PDO_MySQL, or X DevAPI extensions.
All three use mysqlnd driver → drop-in replacement for the MySQL Client Library
5. The mysqlnd library is highly optimized for and tightly integrated into PHP. The MySQL
Client Library cannot offer the same optimizations because it is a general-purpose client
library.
The mysqlnd library is using PHP internal C infrastructure for seamless integration into
PHP. In addition, it is using PHP memory management, PHP Streams (I/O abstraction)
and PHP string handling routines. The use of PHP memory management by mysqlnd
allows, for example, memory savings by using read-only variables (copy on write) and
makes mysqlnd apply to PHP memory limits. Additional advantages include:
● Powerful plugin API to extend feature set
● Asynchronous, non-blocking queries
● 150+ performance statistics
● Ships together with the PHP 5.3, and later, source
● No need to install MySQL Client Library
● Powerful plugins. See Below.
6. Why this talk came about
No three way
comparisons
Examples lacking
Lots of old information Truth versus
mythology
7. PDO
PDO_MYSQL is a driver that implements
the PHP Data Objects (PDO) interface to
enable access from PHP to MySQL
databases (and several other RDMS).
PDO_MYSQL uses emulated prepared
statements by default.
Supported Databases
● CURBID
● SQL Server
● Firebird
● DB2
● Informix
● MySQL
● SQL Server/Sybase
● Oracle
● PostgreSQL
● SQLite
● ODBC/DB2
8. MySQLi
The mysqli extension allows you to
access the functionality provided
by MySQL 4.1 and above.
No client side prepared statements.
9. X DevAPI
The X DevAPI is a common API provided
by multiple MySQL Connectors providing
easy access to relational tables as well as
collections of JSON documents.
The X DevAPI uses the X Protocol, the
new generation client-server protocol of
the MySQL 8.0 server.
NOT AN ORM!!
11. The old mysql connector
End of Life was with PHP 5.5 (2016)
Still a lot of code out there to be ported
DO NOT USE!!! Use mysqli
12. Somethings are going to be similar for all three
After all you are connecting to the same database
So things like authentication will be the same
hostname
username
password
port
schema/database
extra
13. // mysqli
$mysqli = new mysqli("example.com", "user", "password", "database");
$result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message");
$row = $result->fetch_assoc();
// PDO
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message");
$row = $statement->fetch(PDO::FETCH_ASSOC);
// X DevAPI
$session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/p1:33060");
$collection = $schema->getCollection("stuff");
var_dump($collection->find("name = 'Dave'")->execute()->fetchOne());
14. // mysqli
$mysqli = new mysqli("example.com", "user", "password", "database");
$result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message");
$row = $result->fetch_assoc();
// PDO
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message");
$row = $statement->fetch(PDO::FETCH_ASSOC);
// X DevAPI
$session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/p1:33060");
$collection = $schema->getCollection("stuff");
var_dump($collection->find("name = 'Dave'")->execute()->fetchOne());
17. SSL/TLS
MySQL 8.0 is designed to be secure by
default and will generate certificates for you
(if you do not want to use your own).
18. PHP & MySQL -- Things in common
● Open Source
● LAMP Stack
● Extremely Popular
● ‘Backbone’ tech for the internet
● ~25 years old
● Predicted to be dead for ~24.5 years
● Sexy developers!
19. Login to MySQL Instance
Specify
• host
• user
• password (please use good ones)
• schema (optional)
30. X DevAPI SQL function
<?PHP
try {
$session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/world_x");
} catch (Exception $e) {
die("Connection could not be established: " / $e->getMessage());
}
$rows = $session->sql("SELECT * FROM country LIMIT 2")->execute()->fetchAll();
print_r($rows);
31. Parameters & Prepared Statements
PDO allows positional and named parameters
mysqli uses positional ? placeholder
X DevAPI uses named bindings
32. A prepared statement is a feature used to execute the same SQL
statements repeatedly with high efficiency.
1. An SQL statement template is created and sent to the database with certain
parameters marked as reserved ‘place holders’
2. The database syntax checks and performs query optimization on the SQL statement
template, storing the result without executing it
3. Sometime later the application binds the values to the parameter and the database
executes the statement.
The application may execute the statement as many times as it wants with different values
33. Main advantages of prepared statements
• Query plan is only generated once -- big savings in optimization
• Sending only the parameters saves bandwidth over sending the
entire query.
• Useful in reducing SQL injections! The parameter values are
transmitted using a binary protocol and bound parameters do not
need to be escaped as they are never substituted into the query
string directly.
If the original statement template is not derived from external input, SQL injection cannot occur. So
no ‘Little Bobby Drop Tables’
34. Main disadvantage of prepared statements
• For a simple one-off query you need an extra round trip to send
statement and
35. MySQL 8.0 provides support for server-side prepared statements
This support takes advantage of the efficient client/server binary
protocol.
• Less overhead for parsing the statement each time it is executed.
Typically, database applications process large volumes of
almost-identical statements, with only changes to literal or
variable values in clauses such as WHERE for queries and
deletes, SET for updates, and VALUES for inserts.
• Protection against SQL injection attacks. The parameter values
can contain unescaped SQL quote and delimiter characters.
36. Example in SQL
mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
| 5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;
38. $a = 72;
$b = 4;
$c = "Testing";
$stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);");
$stmt->bind_param("iis",$a, $b, $c);
$stmt->execute();
Placeholder for auto_incremented column
39. mysqli
$a = 72;
$b = 4;
$c = "Testing";
$stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);");
$stmt->bind_param("iis",$a, $b, $c);
$stmt->execute();
Data Types
40. mysqli
$a = 72;
$b = 4;
$c = "Testing";
$stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);");
$stmt->bind_param("iis",$a, $b, $c);
$stmt->execute();
Data Types
Character Description
i Integer
d Double
s String
b Blob
44. pdo
$a = 33;
$b = 101;
$c = "Whohoo!";
$conn=->setAttributes(PDO::ATTR_EMULATE_PREPARES,false);
$stmt = $conn->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL, :a, :b, :c)");
$stmt->execute([':a' => $a, ':b' => $b, ':c' => $c]);
This says to use prepared
statements not emulated prepared
statements!
45. Emulated prepared statements - PDO Default
PDO doesn’t send the SQL string to the server during prepare().
● The SQL string is on the client-side, in memory in PDO code.
● The SQL query for is not checked for syntax or other errors!
When execute() runs the query that was saved as an emulated-prepared
query performs string-replacement on the saved SQL string before it
submits the final SQL string to the server.
● This is the first time the server has seen that query so the query must
be have the syntax checked and the passed to query optimizer.
47. MySQL 8.0 provides support for server-side prepared statements.
ALTER TABLE
ALTER USER
ANALYZE TABLE
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} DATABASE
{CREATE | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DO
FLUSH {TABLE | TABLES | TABLES WITH READ
LOCK | HOSTS | PRIVILEGES
| LOGS | STATUS | MASTER | SLAVE |
USER_RESOURCES}
GRANT
INSERT
INSTALL PLUGIN
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
RENAME TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE}
REVOKE
SELECT
SET
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT
| TABLE | VIEW}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
UNINSTALL PLUGIN
UPDATE
48. Buffering
Queries are buffered by default.
Query results are stored in memory, which
allows additional operations like counting the
number of rows or seeking the current result
pointer.
49. mysqli -- unbuffered m04.php
$result = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
52. 'comparisons are odorous' - Shakespeare’s Much Ado About Nothing
So you would think that comparing three
connectors would be comparing ‘apples to
apples’.
Nope
53. CREATE TABLE x (id SERIAL PRIMARY KEY NOT NULL,
a INT UNSIGNED NOT NULL,
b INT UNSIGNED NOT NULL,
c INT UNSIGNED NOT NULL);
#!/usr/bin/python
import random
print("SET AUTOCOMMIT=0;");
for i in range(10):
print(‘BEGIN TRANSACTION;’)
for j in range(1000):
a = random.randint(1,1000000000)
b = random.randint(1,10000000)
c = random.randint(1,1000000)
s = 'INSERT INTO x VALUES (NULL,' + repr(a) + ', ' + repr(b) + ', ' + repr(c) + ');'
print(s)
print(“COMMIT;”)
Schema
Script to generate rows
54. for ($x=0; $x < 1000000 ; $x++) {
$y=rand(1,10000);
$result= = $conn->query(“SELECT * FROM x WHERE id=$y;”);
}
m06-mt.php
real 1m11.647s
user 0m5.911s
sys 0m8.310s
p06-mt.php
real 1m9.242s
user 0m8.578s
sys 0m7.987s
x06x-mt.php
real 3m5.109s
user 1m42.753s
sys 0m27.542s
select(‘*’)
->where(“id = :id”)
->bind([‘id’ => $y])
->execute()-fetchone();
Averages of 10 runs, high/low tossed out
55. And then I changed Hardware...
And yup, the numbers skewed differently and testing multiple
threads, bigger datasets, and other approaches muddled things
further.
PDO was usually just slightly faster than mysqli, just a smidge.
Benchmark your environment
56. Who supports the code?
mysqli
Oracle engineers
X DevAPI
Oracle engineers
PDO
Oracle engineers*
* with reservations
57. Conclusion
Use X DevAPI if you do not like SQL or are using the
MySQL Document Store NoSQL database.
PDO does support multiple databases which is a plus if
you really can support using another data & can port.
mysqli can handle asynchronous calls, mysql->info().