2024年PHP日本大会

统计信息

MySQL Native Driver包含对收集客户端和服务器之间通信统计信息的支持。收集的统计信息主要分为两种类型

  • 客户端统计信息
  • 连接统计信息

使用mysqli扩展时,可以通过两个API调用获得这些统计信息

注意统计信息在使用MySQL Native Driver的所有扩展之间进行汇总。例如,如果mysqli扩展和PDO MySQL驱动程序都设置为使用MySQLnd,则来自mysqli的函数调用和来自PDO的方法调用将影响统计信息。 无法确定已针对MySQL Native Driver编译的任何扩展的特定API调用对特定统计信息的影响程度。

检索统计信息

可以通过调用mysqli_get_client_stats()函数检索客户端统计信息。

可以通过调用mysqli_get_connection_stats()函数检索连接统计信息。

这两个函数都返回一个关联数组,其中统计信息的名称是相应统计数据的键。

MySQL Native Driver统计信息

大多数统计信息与连接相关联,但有些统计信息与进程相关联,在这种情况下会进行说明。

MySQL Native Driver会生成以下统计信息

网络相关统计信息
bytes_sent
从PHP发送到MySQL服务器的字节数。
bytes_received
从MySQL服务器接收到的字节数。
packets_sent
MySQL客户端服务器协议发送的数据包数。
packets_received
从MySQL客户端服务器协议接收的数据包数。
protocol_overhead_in
传入流量的MySQL客户端服务器协议开销(字节)。目前,只有数据包头(4字节)被视为开销。protocol_overhead_in = packets_received * 4
protocol_overhead_out
传出流量的MySQL客户端服务器协议开销(字节)。目前,只有数据包头(4字节)被视为开销。protocol_overhead_out = packets_received * 4
bytes_received_ok_packet
接收到的MySQL客户端服务器协议OK数据包的总字节大小。OK数据包可以包含状态消息。状态消息的长度可能会有所不同,因此OK数据包的大小不是固定的。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_ok
接收到的MySQL客户端服务器协议OK数据包数。
bytes_received_eof_packet
接收到的MySQL客户端服务器协议EOF数据包的总字节大小。EOF的大小取决于服务器版本。此外,EOF可以传输错误消息。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_eof
MySQL客户端服务器协议EOF数据包的数量。 与其他数据包统计信息一样,即使PHP没有接收到预期的数据包,例如错误消息,数据包数量也会增加。
bytes_received_rset_header_packet
MySQL客户端服务器协议结果集头数据包的总字节大小。数据包的大小取决于有效负载(LOAD LOCAL INFILEINSERTUPDATESELECT、错误消息)。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_rset_header
MySQL客户端服务器协议结果集头数据包的数量。
bytes_received_rset_field_meta_packet
MySQL客户端服务器协议结果集元数据(字段信息)数据包的总字节大小。当然,大小会随着结果集中的字段而变化。如果出现COM_LIST_FIELDS,数据包也可能传输错误或EOF数据包。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_rset_field_meta
MySQL客户端服务器协议结果集元数据(字段信息)数据包的数量。
bytes_received_rset_row_packet
MySQL客户端服务器协议结果集行数据包的总字节大小。数据包也可能传输错误或EOF数据包。可以通过从rows_fetched_from_server_normalrows_fetched_from_server_ps中减去bytes_received_rset_row_packet来计算错误和EOF数据包的数量。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_rset_row
MySQL客户端服务器协议结果集行数据包的数量。
bytes_received_prepare_response_packet
MySQL客户端服务器协议OK(预处理语句初始化数据包)(预处理语句初始化数据包)的总字节大小。数据包也可能传输错误。数据包大小取决于MySQL版本。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_prepare_response
MySQL客户端服务器协议OK(预处理语句初始化数据包)(预处理语句初始化数据包)的数量。
bytes_received_change_user_packet
MySQL客户端服务器协议COM_CHANGE_USER数据包的总字节大小。数据包也可能传输错误或EOF。

注意总字节大小包括数据包头的 size(4 字节,参见协议开销)。

packets_received_change_user
MySQL客户端服务器协议COM_CHANGE_USER数据包的数量。
packets_sent_command
从PHP发送到MySQL的MySQL客户端服务器协议命令的数量。 无法知道发送了哪些具体的命令以及发送了多少个命令。
bytes_received_real_data_normal
PHP客户端使用文本协议从mysqlnd提取的有效负载字节数。 这是不源自预处理语句并已由PHP客户端提取的结果集中实际数据的 size。 请注意,虽然mysqlnd可能已从MySQL中提取了完整的结果集,但此统计信息仅计算PHP客户端从mysqlnd实际提取的数据。

将增加该值的代码序列示例如下

$mysqli = new mysqli();
$res = $mysqli->query("SELECT 'abc'");
$res->fetch_assoc();
$res->close();
每次提取操作都会增加该值。

但是,如果结果集仅在客户端缓冲,而没有被提取,例如在以下示例中,则不会增加该统计信息

$mysqli = new mysqli();
$res = $mysqli->query("SELECT 'abc'");
$res->close();

bytes_received_real_data_ps
PHP客户端使用预处理语句协议从mysqlnd提取的有效负载字节数。 这是源自预处理语句并已由PHP客户端提取的结果集中实际数据的 size。 如果PHP客户端随后没有读取结果集,则该值不会增加。 请注意,虽然mysqlnd可能已从MySQL中提取了完整的结果集,但此统计信息仅计算PHP客户端从mysqlnd实际提取的数据。 另请参见bytes_received_real_data_normal
结果集相关统计信息
result_set_queries
生成结果集的查询数量。生成结果集的查询示例:SELECTSHOW 如果读取结果集报头数据包时出错,则不会增加此统计数据。

注意此统计数据可用作 PHP 发送到 MySQL 的查询数量的间接衡量指标。这有助于识别导致数据库负载过高的客户端。

non_result_set_queries
未生成结果集的查询数量。不生成结果集的查询示例:INSERTUPDATELOAD DATA 如果读取结果集报头数据包时出错,则不会增加此统计数据。

注意此统计数据可用作 PHP 发送到 MySQL 的查询数量的间接衡量指标。这有助于识别导致数据库负载过高的客户端。

no_index_used
生成结果集但未使用索引的查询数量。(另请参见 mysqld 启动选项 --log-queries-not-using-indexes)。

注意可以通过调用 mysqli_report(MYSQLI_REPORT_INDEX); 通过异常报告这些查询。可以通过调用 mysqli_report(MYSQLI_REPORT_INDEX ^ MYSQLI_REPORT_STRICT); 将其改为通过警告报告。

bad_index_used
生成结果集但未使用良好索引的查询数量。(另请参见 mysqld 启动选项 --log-slow-queries)。

注意可以通过调用 mysqli_report(MYSQLI_REPORT_INDEX); 通过异常报告这些查询。可以通过调用 mysqli_report(MYSQLI_REPORT_INDEX ^ MYSQLI_REPORT_STRICT); 将其改为通过警告报告。

slow_queries
执行时间超过 long_query_time 秒且需要检查至少 min_examined_row_limit 行的 SQL 语句。
警告

未通过 mysqli_report() 报告。

buffered_sets
通过普通查询(即不是通过预处理语句)返回的已缓冲结果集的数量。

将在客户端缓冲结果集的 API 调用示例:mysqli_query()mysqli_store_result()mysqli_stmt_get_result()

unbuffered_sets
通过普通查询(即不是通过预处理语句)返回的未缓冲结果集的数量。

不会在客户端缓冲结果集的 API 调用示例:mysqli_use_result()

ps_buffered_sets
通过预处理语句返回的已缓冲结果集的数量。

将在客户端缓冲结果集的 API 调用示例:mysqli_stmt_store_result()

ps_unbuffered_sets
通过预处理语句返回的未缓冲结果集的数量。 默认情况下,预处理语句是未缓冲的,因此此统计数据中将计入大多数预处理语句。
flushed_normal_sets
通过普通查询(即不是通过预处理语句)返回的具有未读取数据且已被静默清除的结果集的数量。

注意清除仅发生在未缓冲的结果集上。 在连接上运行新查询之前,必须完全获取未缓冲的结果集,否则 MySQL 将引发错误。如果应用程序未从未缓冲的结果集中获取所有行,则 mysqlnd 将隐式获取结果集以清除线路。 另请参见 rows_skipped_normalrows_skipped_ps

隐式清除的一些可能原因

  • 有问题的客户端应用程序
  • 客户端在找到所需内容后停止读取,但已使 MySQL 计算了比所需更多的记录
  • 客户端应用程序意外停止

flushed_ps_sets
具有未读取数据且已被静默清除的预处理语句结果集的数量。

注意清除仅发生在未缓冲的结果集上。 在连接上运行新查询之前,必须完全获取未缓冲的结果集,否则 MySQL 将引发错误。如果应用程序未从未缓冲的结果集中获取所有行,则 mysqlnd 将隐式获取结果集以清除线路。 另请参见 rows_skipped_normalrows_skipped_ps

隐式清除的一些可能原因

  • 有问题的客户端应用程序
  • 客户端在找到所需内容后停止读取,但已使 MySQL 计算了比所需更多的记录
  • 客户端应用程序意外停止

ps_prepared_never_executed
已准备但从未执行的语句数量。
ps_prepared_once_executed
仅执行一次的预处理语句数量。
rows_fetched_from_server_normal
rows_fetched_from_server_ps
从服务器获取的结果集行的总数。这包括客户端未读取但由于已清除的未缓冲结果集而被隐式获取的行。 另请参见 packets_received_rset_row
rows_buffered_from_client_normal
源自普通查询的已缓冲行的总数。 这是已从 MySQL 获取并在客户端缓冲的行数。

将缓冲结果的查询示例

rows_buffered_from_server_ps
rows_buffered_from_client_normal 相同,但适用于预处理语句。
rows_fetched_from_client_normal_buffered
客户端从普通查询创建的已缓冲结果集中获取的行总数。
rows_fetched_from_client_ps_buffered
客户端从预处理语句创建的已缓冲结果集中获取的行总数。
rows_fetched_from_client_normal_unbuffered
客户端从普通查询创建的未缓冲结果集中获取的行总数。
rows_fetched_from_client_ps_unbuffered
客户端从预处理语句创建的未缓冲结果集中获取的行总数。
rows_fetched_from_client_ps_cursor
客户端从预处理语句创建的光标中获取的行总数。
rows_skipped_normal
rows_skipped_ps
为将来使用保留(当前不支持)。
copy_on_write_saved
copy_on_write_performed
这是一个进程级范围的统计数据。 使用 mysqlnd 时,扩展返回的变量指向 mysqlnd 内部网络结果缓冲区。如果数据未更改,则获取的数据仅在内存中保留一次。但是,对数据的任何修改都将需要 mysqlnd 执行写时复制操作。
explicit_free_result
implicit_free_result
这是一个连接和进程级范围的统计数据。 已释放结果集的总数。
proto_text_fetched_null
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_NULL 的列的总数。
proto_binary_fetched_null
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_NULL 的列的总数。
proto_text_fetched_bit
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_BIT 的列的总数。
proto_binary_fetched_bit
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_BIT 的列的总数。
proto_text_fetched_tinyint
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_TINY 的列的总数。
proto_binary_fetched_tinyint
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_TINY 的列的总数。
proto_text_fetched_short
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_SHORT 的列的总数。
proto_binary_fetched_short
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_SHORT 的列的总数。
proto_text_fetched_int24
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_INT24 的列的总数。
proto_binary_fetched_int24
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_INT24 的列的总数。
proto_text_fetched_int
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_LONG 的列的总数。
proto_binary_fetched_int
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_LONG 的列的总数。
proto_text_fetched_bigint
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_LONGLONG 的列的总数。
proto_binary_fetched_bigint
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_LONGLONG 的列的总数。
proto_text_fetched_decimal
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_DECIMALMYSQL_TYPE_NEWDECIMAL 的列的总数。
proto_binary_fetched_decimal
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_DECIMALMYSQL_TYPE_NEWDECIMAL 的列的总数。
proto_text_fetched_float
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_FLOAT 的列的总数。
proto_binary_fetched_float
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_FLOAT 的列的总数。
proto_text_fetched_double
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_DOUBLE 的列的总数。
proto_binary_fetched_double
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_DOUBLE 的列的总数。
proto_text_fetched_date
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_DATEMYSQL_TYPE_NEWDATE 的列的总数。
proto_binary_fetched_date
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_DATEMYSQL_TYPE_NEWDATE 的列的总数。
proto_text_fetched_year
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_YEAR 的列的总数。
proto_binary_fetched_year
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_YEAR 的列的总数。
proto_text_fetched_time
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_TIME 的列的总数。
proto_binary_fetched_time
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_TIME 的列的总数。
proto_text_fetched_datetime
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_DATETIME 的列的总数。
proto_binary_fetched_datetime
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_DATETIME 的列的总数。
proto_text_fetched_timestamp
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_TIMESTAMP 的列的总数。
proto_binary_fetched_timestamp
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_TIMESTAMP 的列的总数。
proto_text_fetched_string
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_STRINGMYSQL_TYPE_VARSTRINGMYSQL_TYPE_VARCHAR 的列的总数。
proto_binary_fetched_string
从预处理语句(MySQL 二进制协议)获取的类型为 MYSQL_TYPE_STRINGMYSQL_TYPE_VARSTRINGMYSQL_TYPE_VARCHAR 的列的总数。
proto_text_fetched_blob
从普通查询(MySQL 文本协议)获取的类型为 MYSQL_TYPE_TINY_BLOBMYSQL_TYPE_MEDIUM_BLOBMYSQL_TYPE_LONG_BLOBMYSQL_TYPE_BLOB 的列的总数。
proto_binary_fetched_blob
从预处理语句(MySQL 二进制协议)中获取的 MYSQL_TYPE_TINY_BLOBMYSQL_TYPE_MEDIUM_BLOBMYSQL_TYPE_LONG_BLOBMYSQL_TYPE_BLOB 类型列的总数。
proto_text_fetched_enum
从普通查询(MySQL 文本协议)中获取的 MYSQL_TYPE_ENUM 类型列的总数。
proto_binary_fetched_enum
从预处理语句(MySQL 二进制协议)中获取的 MYSQL_TYPE_ENUM 类型列的总数。
proto_text_fetched_set
从普通查询(MySQL 文本协议)中获取的 MYSQL_TYPE_SET 类型列的总数。
proto_binary_fetched_set
从预处理语句(MySQL 二进制协议)中获取的 MYSQL_TYPE_SET 类型列的总数。
proto_text_fetched_geometry
从普通查询(MySQL 文本协议)中获取的 MYSQL_TYPE_GEOMETRY 类型列的总数。
proto_binary_fetched_geometry
从预处理语句(MySQL 二进制协议)中获取的 MYSQL_TYPE_GEOMETRY 类型列的总数。
proto_text_fetched_other
从普通查询(MySQL 文本协议)中获取的前面未列出的 MYSQL_TYPE_* 类型列的总数。

注意理论上,这应该始终为 0

proto_binary_fetched_other
从预处理语句(MySQL 二进制协议)中获取的前面未列出的 MYSQL_TYPE_* 类型列的总数。

注意理论上,这应该始终为 0

连接相关统计信息
connect_success
成功连接尝试的总数。

注意connect_success 包含成功持久连接和非持久连接尝试的总和。因此,成功非持久连接尝试的次数为 connect_success - pconnect_success

pconnect_success
成功持久连接尝试的总数。
connect_failure
连接失败尝试的总数。
reconnect
这是一个进程级范围的统计信息。
active_connections
这是一个进程级范围的统计信息。 活动持久连接和非持久连接的总数。

注意活动非持久连接的总数为 active_connections - active_persistent_connections

active_persistent_connections
这是一个进程级范围的统计信息。 活动持久连接的总数。
explicit_close
显式关闭的连接总数。

示例 #1 导致显式关闭的代码片段示例

  • $link = new mysqli(/* ... */);
    $link->close(/* ... */);
    
  • $link = new mysqli(/* ... */);
    $link->connect(/* ... */);
    
implicit_close
隐式关闭的连接总数。

示例 #2 导致隐式关闭的代码片段示例

  • $link = new mysqli(/* ... */);
    $link->real_connect(/* ... */);
    
  • unset($link)
  • 持久连接:已使用 real_connect 创建池化连接,并且可能设置了未知选项 - 隐式关闭以避免返回具有未知选项的连接
  • 持久连接:ping/change_user 失败,并且 ext/mysqli 关闭连接
  • 脚本执行结束:关闭用户未关闭的连接
disconnect_close
在尝试建立连接期间,C API 调用 mysql_real_connect 指示的连接失败。
in_middle_of_command_close
这是一个进程级范围的统计信息。 在命令执行过程中关闭了一个连接(未获取未完成的结果集,在发送查询后但在检索答案之前,在获取数据时,在使用 LOAD DATA 传输数据时)。
警告

除非使用异步查询,否则只有在 PHP 应用程序意外终止并且 PHP 自动关闭连接时才会发生这种情况。

init_command_executed_count
初始化命令执行的总数。例如:mysqli_options(MYSQLI_INIT_COMMAND , $value) 成功执行的次数为 init_command_executed_count - init_command_failed_count
init_command_failed_count
初始化命令失败的总数。
COM_* 命令相关统计信息
com_quit
com_init_db
com_query
com_field_list
com_create_db
com_drop_db
com_refresh
com_shutdown
com_statistics
com_process_info
com_connect
com_process_kill
com_debug
com_ping
com_time
com_delayed_insert
com_change_user
com_binlog_dump
com_table_dump
com_connect_out
com_register_slave
com_stmt_prepare
com_stmt_execute
com_stmt_send_long_data
com_stmt_close
com_stmt_reset
com_stmt_set_option
com_stmt_fetch
com_daemon
从 PHP 向 MySQL 发送特定 COM_* 命令的尝试总数。 在检查行并立即在发送相应的 MySQL 客户端服务器协议包之前递增统计信息。
警告

如果 MySQLnd 无法通过网络发送数据包,则不会递减统计信息。如果发生故障,MySQLnd 会发出 PHP 警告 发送 %s 数据包时出错。PID=%d。

示例 #3 使用示例

  • 检查 PHP 是否向 MySQL 发送某些命令,例如,检查客户端是否发送 COM_PROCESS_KILL

  • 通过比较 COM_EXECUTECOM_PREPARE 来计算预处理语句执行的平均次数

  • 通过检查 COM_QUERY 是否为零来检查 PHP 是否运行了任何非预处理 SQL 语句

  • 通过检查 COM_QUERYCOM_EXECUTE 来识别运行过多 SQL 语句的 PHP 脚本

其他统计信息
explicit_stmt_close
implicit_stmt_close
这是一个进程级范围的统计信息。 已关闭的预处理语句总数。

注意预处理语句总是显式关闭的。仅当准备失败时才会隐式关闭。

mem_emalloc_count
mem_emalloc_ammount
mem_ecalloc_count
mem_ecalloc_ammount
mem_realloc_count
mem_realloc_ammount
mem_efree_count
mem_malloc_count
mem_malloc_ammount
mem_calloc_count
mem_calloc_ammount
mem_ealloc_count
mem_ealloc_ammount
mem_free_count
这是一个进程级范围的统计信息。 内存管理调用。
command_buffer_too_small
在将命令从 PHP 发送到 MySQL 时,网络命令缓冲区扩展的次数。 MySQLnd 为每个连接分配一个 mysqlnd.net_cmd_buffer_size 字节的内部命令/网络缓冲区。 如果 MySQL 客户端服务器协议命令(例如 COM_QUERY(普通查询))不适合缓冲区,MySQLnd 将扩展缓冲区以满足发送命令的需求。每当为一个连接扩展缓冲区时,command_buffer_too_small 将递增 1。 如果 MySQLnd 必须为几乎每个连接将其缓冲区大小从初始大小 mysqlnd.net_cmd_buffer-size 字节扩展到更大的大小,则应考虑增加默认大小以避免重新分配。
connection_reused
持久连接被重用的总次数。
添加注释

用户贡献的注释

此页面没有用户贡献的注释。
To Top