Professional Documents
Culture Documents
Webinar2final
Webinar2final
Building High Performance and High Traffic PHP Applications with MySQL Part 2: Best Practices
Johannes Schlter & Ulf Wendel MySQL Engineering: Connectors & Client Connectivity Wei-Chen Chiu MySQL Product Marketing Manager
About MySQL
Founded in 1995 Acquired by Sun Microsystems in February 2008 Acquired by Oracle in January 2010 The Worlds Most Popular Open Source Database MySQL Commercial Editions Available
MySQL Customers
Web
OEM / ISVs
SaaS, Hosting
Telecommunication s
Enterprise 2.0
Building High Performance and High Traffic PHP Applications with MySQL Part 2: Best Practices
Johannes Schlter MySQL Engineering: Connectors & Client Connectivity
Introduction
PHP Application
ext/mysql
mysqli
PDO_mysql
mysqlnd / libmysql
MySQL Server
PHP Application
ext/mysql
mysqli
PDO_mysql
mysqlnd / libmysql Today we're mostly talking about this MySQL Server
Huge number of of short connections A web request should be handled in way less than a second Many requests happen in parallel Database server close to Web-Server Low latency Sometimes MySQL installed on the same machine as the Web server
Connection Basics
Connection Stages
Transport Layer
Unix Domain Socket Local communication on Unix/Linux systems /tmp/mysql.sock Windows Named Pipes Local communication on Windows systems TCP/IP Socket Network-based communication TCP Port 3306
mysql_connect(':/tmp/mysql.sock', 'user', 'password'); new mysqli('localhost', 'user', 'password', 'schema', 0, '/tmp/mysql.sock'); new PDO('mysql:unix_socket=/tmp/mysql.sock', 'user', 'password');
Default Location when using localhost compiled in php.ini
Persistent Connections
The initial problem Establishing a connection takes time A solution Re-Use an existing MySQL connections over multiple requests
The problem there A connection has associated resources Session variables, temporary tables, PS handles, ..
A solution Reset the connection using change_user MySQL call The consequence Saves transport creation and initial MySQL handshake
Connection Options
$mysqli = mysqli_init(); $mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 5); $mysqli->ssl_set($key, $cert, $ca, $capath, $cipher); $mysqli->real_connect( 'localhost', 'my_user', 'my_password', 'my_db');
Compression
MySQL compresses each packet individually Each returned row is (usually) one packet Compression costs CPU to reduce network IO With bad luck compression consumes more IO SELECT id FROM table Will most likely show bad compression ratio, even with many rows SELECT complete_article_text FROM table Might have good compression ratio
Encryption
SSL Handshake happens only once MySQL doesn't see encryption http://stunnel.org
Character Sets
Query Execution
Buffered Results Copies the complete result set to the client (PHP) Minimal memory usage on Server
Unbuffered Results Copies rows in sequence as needed Minimal memory usage on Client
Result Sets
$result= $mysqli->query($sql, $mode); $mode is either MYSQLI_STORE_RESULT (buffered) or MYSQLI_USE_RESULT (unbuffered) Free buffered result sets mysqli_free_result($result);
Pros of Multi Query: Reduced latency in communication Base technology needed for stored procedures Cons of Multi Query: No automatic association of a result set to a query Higher risk of danger with SQL injection Security: $mysql->multi_query( 'SELECT * FROM t WHERE id = '.$_GET['id']);
$_GET['id'] = '23; DROP TABLE t';
including little meta data and the query test The server will respond with an OK package if there are no result sets or an error package or
An result set header package Followed by a field header packages for each field (column) containing field meta data (types, max length, ) Followed by a row package for each row All data is transferred as string Followed by an EOF package
Prepared Statements
Prepared Statements
Client
SELECT foo FROM bar WHERE id = 42
Server
Handle
Handle Param 1: 42 Resultset(s)
Query database
A COM_PREPARE package is similar to COM_QUERY The server responds with either OK or ERR, the OK package returns a statement ID The COM_EXECUTE package refers to this ID and also includes all bound values The result is similar to COM_QUERY
With persistent connections the connection is held But PS handles are freed pscache is an experimental plugin helping We will talk about plugins in
The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP. http://php.net/intro.pdo It is heavily build around Prepared Statements (PS) For handling PS it has to do two things:
Mapping placeholders Do PS emulation (optional)
<?php $query = "/* ' */ select ? as f1, 'bar' as f2"; $pdo = new PDO("mysql:dbname=...;host=...", "...", "..."); $stmt = $pdo->prepare($query); if (!$stmt->execute(array("foo"))) { $errInfo = $stmt->errorInfo(); print_r($errInfo); } ?>
PDO Emulation
Even $pdo->query($sql); will go through the prepared statements API in PDO MySQL historically did not support all statements to be prepared
OPTIMIZE TABLE, ANALYZE TABLE, ALTER TABLE,
PDO falls back on emulation, even if emulation failed due to other errors PDO developers decided to use emulation by default PDO::MYSQL_ATTR_DIRECT_QUERY
mysqlnd Statistics
Statistics Cookbook
mysql_query()
mysqli::query()
PDO::query()
Plugin Hook
Network
mysqlnd Plugins
The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracles products remains at the sole discretion of Oracle.
Thank You!
Johannes Schlter johannes.schlueter@oracle.com Ulf Wendel Ulf.wendel@oracle.com