php-doc-en/reference/mysqli/mysqlnd.xml

744 lines
18 KiB
XML
Raw Normal View History

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<chapter xml:id="mysqli.mysqlnd" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>The MySQL Native Driver</title>
<para>
This section of the manual provides an overview of the MySQL Native
Driver.
</para>
<para>
<emphasis role="bold">What is it?</emphasis>
</para>
<para>
MySQL Native Driver is a replacement for the MySQL Client Library
(libmysql). MySQL Native Driver is part of the official PHP 5.3 and
PHP 6 branches.
</para>
<para>
The MySQL database extensions MySQL extension,
<literal>mysqli</literal> and PDO MYSQL all communicate with the MySQL
server. In the past, this was done by the extension using the services
provided by the MySQL Client Library. The extensions were compiled
against the MySQL Client Library in order to use its client-server
protocol.
</para>
<para>
With MySQL Native Driver there is now an alternative, as the MySQL
database extensions can be compiled to use MySQL Native Driver instead
of the MySQL Client Library.
</para>
<para>
MySQL Native Driver is written in C as a PHP extension.
</para>
<para>
<emphasis role="bold">What it is not</emphasis>
</para>
<para>
Although MySQL Native Driver is written as a PHP extension, it is
important to note that it does not provide a new API to the PHP
programmer. The programmer APIs for MySQL database connectivity are
provided by the MySQL extension, <literal>mysqli</literal> and PDO
MYSQL. These extensions can now use the services of MySQL Native
Driver to communicate with the MySQL Server. Therefore, you should not
think of MySQL Native Driver as an API.
</para>
<para>
<emphasis role="bold">Why use it?</emphasis>
</para>
<para>
Using the MySQL Native Driver offers a number of advantages over using
the MySQL Client Library.
</para>
<para>
The older MySQL Client Library was written by MySQL AB (now Sun Microsystems, Inc.)
and so was released under the MySQL license. This ultimately led to MySQL
support being disabled by default in PHP. However, the MySQL Native Driver has
been developed as part of the PHP project, and is therefore released
under the PHP license. This removes licensing issues that have been
problematic in the past.
</para>
<para>
Also, in the past, you needed to build the MySQL database extensions
against a copy of the MySQL Client Library. This typically meant you
needed to have MySQL installed on a machine where you were building
the PHP source code. Also, when your PHP application was running, the
MySQL database extensions would call down to the MySQL Client library
file at run time, so the file needed to be installed on your system.
With MySQL Native Driver that is no longer the case as it is included
as part of the standard distribution. So you do not need MySQL
installed in order to build PHP or run PHP database applications.
</para>
<para>
Because MySQL Native Driver is written as a PHP extension, it is
tightly coupled to the workings of PHP. This leads to gains in
efficiency, especially when it comes to memory usage, as the driver
uses the PHP memory management system. It also supports the PHP memory
limit. Using MySQL Native Driver leads to comparable or better
performance than using MySQL Client Library, it always ensures the
most efficient use of memory. One example of the memory efficiency is
the fact that when using the MySQL Client Library, each row is stored
in memory twice, whereas with the MySQL Native Driver each row is only
stored once in memory.
</para>
<para>
<emphasis role="bold">Special features</emphasis>
</para>
<para>
MySQL Native Driver also provides some special features not available
when the MySQL database extensions use MySQL Client Library. These
special features are listed below:
</para>
<itemizedlist>
<listitem>
<para>
Improved persistent connections
</para>
</listitem>
<listitem>
<para>
The special function <function>mysqli_fetch_all</function>
</para>
</listitem>
<listitem>
<para>
Performance statistics calls:
<function>mysqli_get_cache_stats</function>,
<function>mysqli_get_client_stats</function>,
<function>mysqli_get_connection_stats</function>
</para>
</listitem>
</itemizedlist>
<para>
The performance statistics facility can prove to be very useful in
identifying performance bottlenecks.
</para>
<para>
MySQL Native Driver also allows for persistent connections when used
with the <literal>mysqli</literal> extension.
</para>
<para>
<emphasis role="bold">SSL Support</emphasis>
</para>
<para>
Currently, MySQL Native Driver does not support SSL. This means that
<function>mysqli_ssl_set</function> will generate an error if called
while using MySQL Native Driver.
</para>
<para>
<emphasis role="bold">Installation on Unix</emphasis>
</para>
<para>
By default the MySQL database extensions are configured to use MySQL
Client Library. In order to use the MySQL Native Driver, PHP needs to
be built specifying that the MySQL database extensions are compiled
with MySQL Native Driver support. This is done through configuration
options prior to building the PHP source code.
</para>
<para>
For example, to build the MySQL extension, <literal>mysqli</literal>
and PDO MYSQL using the MySQL Native Driver, the following command
would be given:
</para>
<programlisting role="shell">./configure --with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
[other options]</programlisting>
<para>
<emphasis role="bold">Installation on Windows</emphasis>
</para>
<para>
In the official PHP distributions from 5.3 onwards, MySQL Native
Driver is enabled by default, so no additional configuration is
required to use it. All MySQL database extensions will use MySQL
Native Driver in this case.
</para>
<para>
<emphasis role="bold">Using Persistent Connections</emphasis>
</para>
<para>
The MySQL database extensions do not support persistent connections
when used with the MySQL Client Library. However, they do when using
MySQL Native Driver. When creating a connection the hostname is
prepended with <quote>p:</quote>. This is demonstrated by the
following code snippet, which creates a new connection using
<literal>mysqli</literal>:
</para>
<programlisting role="php">$host="p:localhost";
$port=3306;
$socket="/tmp/mysql.sock";
$user="root";
$password="password";
$dbname="test";
$conn = new mysqli($host, $user, $password, $dbname, $port, $socket)
or die ('Could not connect to the database server' . mysqli_connect_error());</programlisting>
<para>
<emphasis role="bold">Using
<function>mysqli_fetch_all</function></emphasis>
</para>
<para>
If you are using <literal>mysqli</literal> with the MySQL Native
Driver, you have access to the new API call
<function>mysqli_fetch_all</function>.
</para>
<para>
As <function>mysqli_fetch_all</function> returns all the rows as an
array in a single step, it may consume more memory than some similar
functions such as <function>mysqli_fetch_array</function>, which only
returns one row at a time from the result set. Further, if you need to
iterate over the result set, you will need a looping construct that
will further impact performance. For these reasons
<function>mysqli_fetch_all</function> should only be used in those
situations where the fetched result set will be sent to another layer
for processing.
</para>
<para>
<emphasis role="bold">Using Statistical Data</emphasis>
</para>
<para>
MySQL Native Driver contains support for gathering statistics on the
communication between the client and the server. The statistics
gathered are of three main types:
</para>
<itemizedlist>
<listitem>
<para>
Client statistics
</para>
</listitem>
<listitem>
<para>
Connection statistics
</para>
</listitem>
<listitem>
<para>
Zval cache statistics
</para>
</listitem>
</itemizedlist>
<para>
If you are using the <literal>mysqli</literal> extension, these
statistics can be obtained through three API calls:
</para>
<itemizedlist>
<listitem>
<para>
<function>mysqli_get_client_stats</function>
</para>
</listitem>
<listitem>
<para>
<function>mysqli_get_connection_stats</function>
</para>
</listitem>
<listitem>
<para>
<function>mysqli_get_cache_stats</function>
</para>
</listitem>
</itemizedlist>
<para>
<emphasis role="bold">Accessing Client Statistics</emphasis>
</para>
<para>
To access client statistics, you need to call
<function>mysqli_get_client_stats</function>. The function call does
not require any parameters.
</para>
<para>
The function returns an associative array that contains the name of
the statistic as the key and the statistical data as the value.
</para>
<para>
Client statistics can also be accessed by calling the
<function>phpinfo</function> function.
</para>
<para>
<emphasis role="bold">Accessing Connection Statistics</emphasis>
</para>
<para>
To access connection statistics call
<function>mysqli_get_connection_stats</function>. This takes the
database connection handle as the parameter.
</para>
<para>
The function returns an associative array that contains the name of
the statistic as the key and the statistical data as the value.
</para>
<para>
<emphasis role="bold">Accessing Zval Cache Statistics</emphasis>
</para>
<para>
The MySQL Native Driver also collects statistics from its internal
Zval cache. These statistics can be accessed by calling
<function>mysqli_get_cache_stats</function>.
</para>
<para>
The Zval cache statistics obtained may lead to a tweaking of
<filename>php.ini</filename> settings related to the Zval cache,
resulting in better performance.
</para>
<para>
<emphasis role="bold">Statistics returned by MySQL Native
Driver</emphasis>
</para>
<para>
The following table shows a list of statistics returned by the
<function>mysqli_get_client_stats</function>,
<function>mysqli_get_connections_stats</function> and
<function>mysqli_get_cache_stats</function> functions.
</para>
<informaltable>
<tgroup cols="1">
<colspec colwidth="30*"/>
<tbody>
<row>
<entry><emphasis role="bold">Statistic</emphasis></entry>
</row>
<row>
<entry>bytes_sent</entry>
</row>
<row>
<entry>bytes_received</entry>
</row>
<row>
<entry>packets_sent</entry>
</row>
<row>
<entry>packets_received</entry>
</row>
<row>
<entry>protocol_overhead_in</entry>
</row>
<row>
<entry>protocol_overhead_out</entry>
</row>
<row>
<entry>bytes_received_ok_packet</entry>
</row>
<row>
<entry>bytes_received_eof_packet</entry>
</row>
<row>
<entry>bytes_received_rset_header_packet</entry>
</row>
<row>
<entry>bytes_received_rset_field_meta_packet</entry>
</row>
<row>
<entry>bytes_received_rset_row_packet</entry>
</row>
<row>
<entry>bytes_received_prepare_response_packet</entry>
</row>
<row>
<entry>bytes_received_change_user_packet</entry>
</row>
<row>
<entry>packets_sent_command</entry>
</row>
<row>
<entry>packets_received_ok</entry>
</row>
<row>
<entry>packets_received_eof</entry>
</row>
<row>
<entry>packets_received_rset_header</entry>
</row>
<row>
<entry>packets_received_rset_field_meta</entry>
</row>
<row>
<entry>packets_received_rset_row</entry>
</row>
<row>
<entry>packets_received_prepare_response</entry>
</row>
<row>
<entry>packets_received_change_user</entry>
</row>
<row>
<entry>result_set_queries</entry>
</row>
<row>
<entry>non_result_set_queries</entry>
</row>
<row>
<entry>no_index_used</entry>
</row>
<row>
<entry>bad_index_used</entry>
</row>
<row>
<entry>slow_queries</entry>
</row>
<row>
<entry>buffered_sets</entry>
</row>
<row>
<entry>unbuffered_sets</entry>
</row>
<row>
<entry>ps_buffered_sets</entry>
</row>
<row>
<entry>ps_unbuffered_sets</entry>
</row>
<row>
<entry>flushed_normal_sets</entry>
</row>
<row>
<entry>flushed_ps_sets</entry>
</row>
<row>
<entry>ps_prepared_never_executed</entry>
</row>
<row>
<entry>ps_prepared_once_executed</entry>
</row>
<row>
<entry>rows_fetched_from_server_normal</entry>
</row>
<row>
<entry>rows_fetched_from_server_ps</entry>
</row>
<row>
<entry>rows_buffered_from_client_normal</entry>
</row>
<row>
<entry>rows_buffered_from_client_ps</entry>
</row>
<row>
<entry>rows_fetched_from_client_normal_buffered</entry>
</row>
<row>
<entry>rows_fetched_from_client_normal_unbuffered</entry>
</row>
<row>
<entry>rows_fetched_from_client_ps_buffered</entry>
</row>
<row>
<entry>rows_fetched_from_client_ps_unbuffered</entry>
</row>
<row>
<entry>rows_fetched_from_client_ps_cursor</entry>
</row>
<row>
<entry>rows_skipped_normal</entry>
</row>
<row>
<entry>rows_skipped_ps</entry>
</row>
<row>
<entry>copy_on_write_saved</entry>
</row>
<row>
<entry>copy_on_write_performed</entry>
</row>
<row>
<entry>command_buffer_too_small</entry>
</row>
<row>
<entry>connect_success</entry>
</row>
<row>
<entry>connect_failure</entry>
</row>
<row>
<entry>connection_reused</entry>
</row>
<row>
<entry>reconnect</entry>
</row>
<row>
<entry>pconnect_success</entry>
</row>
<row>
<entry>active_connections</entry>
</row>
<row>
<entry>active_persistent_connections</entry>
</row>
<row>
<entry>explicit_close</entry>
</row>
<row>
<entry>implicit_close</entry>
</row>
<row>
<entry>disconnect_close</entry>
</row>
<row>
<entry>in_middle_of_command_close</entry>
</row>
<row>
<entry>explicit_free_result</entry>
</row>
<row>
<entry>implicit_free_result</entry>
</row>
<row>
<entry>explicit_stmt_close</entry>
</row>
<row>
<entry>implicit_stmt_close</entry>
</row>
<row>
<entry>mem_emalloc_count</entry>
</row>
<row>
<entry>mem_emalloc_ammount</entry>
</row>
<row>
<entry>mem_ecalloc_count</entry>
</row>
<row>
<entry>mem_ecalloc_ammount</entry>
</row>
<row>
<entry>mem_erealloc_count</entry>
</row>
<row>
<entry>mem_erealloc_ammount</entry>
</row>
<row>
<entry>mem_efree_count</entry>
</row>
<row>
<entry>mem_malloc_count</entry>
</row>
<row>
<entry>mem_malloc_ammount</entry>
</row>
<row>
<entry>mem_calloc_count</entry>
</row>
<row>
<entry>mem_calloc_ammount</entry>
</row>
<row>
<entry>mem_realloc_count</entry>
</row>
<row>
<entry>mem_realloc_ammount</entry>
</row>
<row>
<entry>mem_free_count</entry>
</row>
<row>
<entry>proto_text_fetched_null</entry>
</row>
<row>
<entry>proto_text_fetched_bit</entry>
</row>
<row>
<entry>proto_text_fetched_tinyint</entry>
</row>
<row>
<entry>proto_text_fetched_short</entry>
</row>
<row>
<entry>proto_text_fetched_int24</entry>
</row>
<row>
<entry>proto_text_fetched_int</entry>
</row>
<row>
<entry>proto_text_fetched_bigint</entry>
</row>
<row>
<entry>proto_text_fetched_decimal</entry>
</row>
<row>
<entry>proto_text_fetched_float</entry>
</row>
<row>
<entry>proto_text_fetched_double</entry>
</row>
<row>
<entry>proto_text_fetched_date</entry>
</row>
<row>
<entry>proto_text_fetched_year</entry>
</row>
<row>
<entry>proto_text_fetched_time</entry>
</row>
<row>
<entry>proto_text_fetched_datetime</entry>
</row>
<row>
<entry>proto_text_fetched_timestamp</entry>
</row>
<row>
<entry>proto_text_fetched_string</entry>
</row>
<row>
<entry>proto_text_fetched_blob</entry>
</row>
<row>
<entry>proto_text_fetched_enum</entry>
</row>
<row>
<entry>proto_text_fetched_set</entry>
</row>
<row>
<entry>proto_text_fetched_geometry</entry>
</row>
<row>
<entry>proto_text_fetched_other</entry>
</row>
<row>
<entry>proto_binary_fetched_null</entry>
</row>
<row>
<entry>proto_binary_fetched_bit</entry>
</row>
<row>
<entry>proto_binary_fetched_tinyint</entry>
</row>
<row>
<entry>proto_binary_fetched_short</entry>
</row>
<row>
<entry>proto_binary_fetched_int24</entry>
</row>
<row>
<entry>proto_binary_fetched_int</entry>
</row>
<row>
<entry>proto_binary_fetched_bigint</entry>
</row>
<row>
<entry>proto_binary_fetched_decimal</entry>
</row>
<row>
<entry>proto_binary_fetched_float</entry>
</row>
<row>
<entry>proto_binary_fetched_double</entry>
</row>
<row>
<entry>proto_binary_fetched_date</entry>
</row>
<row>
<entry>proto_binary_fetched_year</entry>
</row>
<row>
<entry>proto_binary_fetched_time</entry>
</row>
<row>
<entry>proto_binary_fetched_datetime</entry>
</row>
<row>
<entry>proto_binary_fetched_timestamp</entry>
</row>
<row>
<entry>proto_binary_fetched_string</entry>
</row>
<row>
<entry>proto_binary_fetched_blob</entry>
</row>
<row>
<entry>proto_binary_fetched_enum</entry>
</row>
<row>
<entry>proto_binary_fetched_set</entry>
</row>
<row>
<entry>proto_binary_fetched_geometry</entry>
</row>
<row>
<entry>proto_binary_fetched_other</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"../../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->