author: selfimpr
blog: http://blog.youkuaiyun.com/lgg201
mail: lgg860911@yahoo.com.cn
item
|
mysql_query
|
mysql_unbuffered_query
|
函数原型
|
resource mysql_query($query[, $link = NULL]);
|
resource mysql_unbuffered_query($query[, $link = NULL]);
|
数据读取的处理流程
|
-
以mysqlnd为例
-
源代码中有分歧的入口php_mysqlnd_conn_store_result_pub
-
检查连接的最后一次执行的SQL是否SELECT,
检查连接当前状态是否是抓取数据,
如果不是则返回错误
-
执行php_mysqlnd_res_store_result_pub函数
-
构造结果集对象MYSQLND_RES:
增加连接zval的引用计数,
设置抓取接口函数(mysqlnd_fetch_row_buffered),
抓取缓冲区长度获取函数(mysqlnd_fetch_lengths_buffered)
-
在结果集对象成员中分配结果数据存储缓冲区空间(默认16000),
分配存储长度使用的空间(field_count个unsigned
long的空间)
-
调用php_mysqlnd_res_store_result_fetch_data_pub函数读取数据
-
分配数据存储空间(1个MYSQLND_RES_BUFFERED结构,
free_rows(硬编码1)个MYSQLND_MEMORY_POOL_CHUNK指针)
-
设置结果集的行解码器(php_mysqlnd_rowp_read_binary_protocol, php_mysqlnd_rowp_read_text_protocol)
-
分配行数据包存储空间,
并初始化数据包成员属性
-
循环按行读取服务端响应数据
-
自动检查并扩展行缓冲区(第8步分配的MYSQLND_RES_BUFFERED->row_buffers),
以10%的速度扩展
-
维护free_rows计数,
用于上一步的缓冲区自动扩展
-
将读取到的包中的行数据写入到行缓冲区中对应行上(数组对应下标)
-
更新已获取的行数
-
清理包(row_packet)的临时数据
-
返回结果的构建
-
检查是否有row_count(即是否有结果)
-
分配row_count * field_count个zval结构
-
清空分配的所有zval的内存空间(memset(p,
0, size))
-
节省内存,
释放多余分配的行缓冲区内存空间
-
变更连接的状态(结果集已就绪)
-
初始化数据集的游标(指针)到数据首指针
-
设置受影响行数为row_count(源码注释:
libmysql文档说明affected_rows同样适用于SELECT语句)
-
释放用于按行读取的row_packet数据结构
-
将结果集对象作为返回值返回
|
-
以mysqlnd为例
-
源代码中有分歧的入口php_mysqlnd_conn_use_result_pub
-
检查连接的最后一次执行的SQL是否SELECT,
检查连接当前状态是否是抓取数据,
如果不是则返回错误
-
执行php_mysqlnd_res_use_result_pub函数
-
根据协议不同初始化结果集基本属性
-
读取抓取接口函数
-
抓取缓冲区长度获取函数
-
行解码器(二进制协议/文本协议两种)
-
创建结果集内存池(默认16000)
-
分配一个数据存储空间(无缓冲-MYSQLND_RES_UNBUFFERED)
-
设置按行的包读取函数
-
初始化行的封装结构体(struct st_mysqlnd_packet_row)基本属性
-
结果集内存池
-
字段数(发送查询时已得到)
-
是否二进制协议
-
字段元数据
-
将结果集对象作为返回值返回
|