PHP中mysql查询全部过程_PHP到MySQL数据查询过程概述_MySQL
摘要
本文概述了从PHP层发起mysql查询请求到mysql server 返回结果集的工作流程,并简单描述了各层可能涉及到的动作和组件。从全局把握整个交互过程。
PHP层到MySQL层
Php到sql组件层次如下图所示:
ext/mysqli和ext/mysql 是客户端的扩展程序库(库函数) ,在客户端脚本层面的扩展库。 Mysqli库是mysql库的扩展版本,扩展版本增加了列版定(Bind Column)绑定。PDO (PHP Data Object) 是另外一种面向数据对象的扩展库。这些扩展库直接面向编程者,而它的底层实现是mysql连接引擎(如mysqlnd和libmysql )(参考 http://bbs.chinaunix.net/thread-3679393-1-1.html 、http://blog.csdn.net/treesky/article/details/7286098 )。
mysqlnd和libmysql 是PHP端(客户端)的数据库连接驱动引擎。libmysql 是通用的数据库连接引擎,而mysqlnd是专属PHP开发的连接引擎,从属于Zend中。
当PHP通过调用扩展库(ext/mysqli和ext/mysql)中的mysql_query() 函数进行数据库查询的时候,Zend引擎将通过mysql(mysqlnd和libmysql)查询引擎向MySQL服务器发出查询请求。
MySQL层的数据查询
MySQL服务器接受到客户端的查询请求后,查询执行过程如上图所示:
1. 查询缓存,如果命中则直接将结果集返回给到客户端,否则进入步骤2
2. 对SQL语句依次进行解析、预处理、查询优化等操作,最终生成查询执行计划(select的查询执行计划可以通过explain select 查看)
3. MySQL服务端的查询执行引擎将依据查询执行计划 调用存储引擎对数据进行查询。当SQL语句的最后一层关联被执行后,将产生查询结果集
4. 查询结果集发送到客户端,传回的方式有两种:MySQL服务端缓存结果集 或 不缓存,这个由参数SQL_BUFFER_RESULT设置。 并且,如果用户设置了SQL_CACHE 那么本次的查询的结果集的一份副本存储于 查询缓存 中(步骤1相关)。
SQL_CACHE参数的启示:
将复杂的(多个关联)查询分解为多条简单的查询,因为
1)简单查询的缓存命中搞、
2)复杂查询结果的缓存易失效(关联太多表)
3)简单查询锁的持有率低
MySQL Server 到 PHP层
通信模式MySQL Server和客户端的通信采用“半双工通信”,意思是:客户端和服务端只能有一个在读,并且另外一个必须是写。
优点:协议简单,客户端和服务端的写权限是互斥的
缺点:无法进行流量控制,一端开始发送消息,另一端要完整的接受这个消息后才能响应它。
启示:服务端查询后的结果集发送给客户端,客户端(客户端的查询引擎,例如mysqlnd)必须完整的接受。所以,如果只需要少数行,记得在sql语句添加使用limit,少用select *。
结果集回传模式结果集回传中,每一行记录都通过 客户端-服务器通信协议进行包装,然后再交接给下层的tcp协议;当然,在tcp层,可以先缓存每行记录的协议包,组成大包在发出(对应用层透明)。
MySQL服务端只有将结果集全部发送给客户端后,才能释放结果集所占用的buffer。
服务端缓存模式
客户端命令: mysql_unbuffer_query(),在客户端的sql驱动扩展(mysqlnd)中不设置结果集的缓存,所以在fecth_array_xxx从结果集中读取一条记录时,需要从服务端的缓冲区中读取。
服务端无缓存模式
客户端命令: mysql_query(),在客户端的sql驱动扩展(mysqlnd)中设置了buffer用于缓存服务端的结果集,所以在fecth_array_xxx从结果集中读取一条记录时,是直接从mysqlnd扩展的缓冲区中取得row。
小结
如果结果集很大: 服务端无缓存模式可以减少服务端的内存压力哟,但是占用客户端的内存。这样只有看情况取舍了。
PHP层到用户层
在客户端,于服务端对接的是mysql扩展引擎(libmysql 或者 mysqlnd),而用户层是通过扩展库(ext/mysql 或 ext/mysqli)和mysql引擎进行交互(启示就是调用引擎的api读取结果集)。
引擎libmysql 和 mysqlnd 的机制并不同,主要区别是mysqlnd是转为php写的,被编译到zend内部。而libmysql是通用的库,zend需要调用该库实现数据库的连接。在这种却别下,mysqlnd和zend具有更好的粘合性,在数据传输到用户层时,少了一层数据的拷贝。具体的架构区别如下图所示。图中,五角星表示缓存 buffer。
vcWxvrLjw+ZteXNxbEluZLrNbGlibXlzcWwgysdNeVNxbCBTZXJ2ZXK2y7XEx/22r7PM0PKho8bk1tCjrGxpYm15c3FsysfNqNPDtcRNeVNRTLLp0a/H/bavs8zQ8qOstvhteXNxbG5kysfXqM6qUEhQyejWw7XEu/nT2lplbmTS/cfmtcRTUUzH/bavo6y8tG15c3FsbmS1xMr9vt3H/bavtq/X99Do0qq+rbn9WmVuZLrNbXlzcWxzZXJ2ZXK9u7ulo6y2+GxpYm15c3Fs1rG907rNbXlzcWxzZXJ2ZXK9u7ultcShozwvcD4NCjxwPrbUscijujxiciAvPg0KZXh0L215c3FsaaOou/LV32V4dC9teXNxbKOpus1saWJteXNxbLXEyv2+3b/isunRr9bQtcS5/bPMzqqjujxiciAvPg0KMaOpbXlzcWnP8mxpYm15c3Fsx/22r7eiy82y6dGvx+vH8zxiciAvPg0KMqOpTGlibXlzcWzWtNDQx+vH87KitcO1vb3hufu8r7TmtKLT8mxpYm15c3FstcRidWZmZXJz1tA8YnIgLz4NCjOjqU15c3Fsacnqx+vE2rTmo7p6dmFs1ri2qLXE0ru/6WJ1ZmZlcjxiciAvPg0KNKOpTXlzcWlptNNsaWJteXNxbL+9sbS94bn7vK+1vXp2YWzWuLaotcRidWZmZXLW0DxiciAvPg0KZXh0L215c3FsaaOou/LV32V4dC9teXNxbKOpus1teXNxbG5ktcTK/b7dv+Ky6dGv1tC1xLn9s8zOqqO6PGJyIC8+DQoxKSBteXNxac/ybXlzcWxuZMf9tq+3osvNsunRr8frx/M8YnIgLz4NCjIpIG15c3FsbmTH/bavzai5/XplbmTS/cfm1rTQ0HNxbLLp0a+jrL3hufu8r7XEw7/Su9DQ08nSu7j2YnVmZmVytOa0oqOouPe49mJ1ZmZlcsrHt9bJorXEo6k8YnIgLz4NCjMpIE15c3FsbmS0tL2otuC49np2YWyjrLKi1rjP8tXi0KlidWZmZXJzPC9wPg0KPHA+wP3I56O6PGJyIC8+DQrU2mV4dC9teXNxbCAmYW1wOyBsaWJteXNxbCDW0KOsbGlibXlzcWzH/bav1rTQ0FNRTNPvvuS687XDtb294bn7vK9Sb3cxflJvdzOjrMi7uvNleHQvbXlzcWy9q73hufu8r7+9sbS1vXplbmQgYnVmZmVy1tCjrNauuvNteXNxbGlfZmV0Y2hfeHh4uq/K/bTTuMPH+NPyxNq05tbQtsHIob3hufu8r9bQtcTE2sjdoaM8YnIgLz4NCtTaZXh0L215c3FsaSAmYW1wOyBteXNxbEluZCDW0KOsbXlzcWxuZCDH/bav1rTQ0FNRTNPvvuS1w7W9veG5+7yvUm93MX5Sb3czo6zG5NbQo6zDv7j2cm931rG909PJemVuZLXE0ru49mJ1ZmZlcrTmtKKjrLKi08nSu7j2enZhbNa4z/Kho7/Nu6e2y82ouf3Ts8nk1rG907TTuMPE2rTmx/jT8tbQtsHIob3hufvKtc/WbXlzcWxpX2ZldGNoX3h4eKGjPC9wPg0KPGgyIGlkPQ=="小结-1">小结
mysqlnd和zend更具有粘合性,在sql查询驱动中,mysqlnd通过zend引擎访问数据库,并直接将将结果存储域zend的buffer中,相比libmysql驱动(独立于zend),少了一次结果集缓存拷贝。
本文原创发布php中文网,转载请注明出处,感谢您的尊重!
PHP中mysql查询全部过程_PHP到MySQL数据查询过程概述_MySQL相关推荐
- php mysql 无法查询中文名字_PHP连接MySQL查询中文时显示Notice: Trying to get property of non-object...
1.保证MySQL和PHP的编码一致 MySQL 修改整个数据库的编码格式 注意:如果数据不重要的话,可以直接使用更改数据库的编码格式,再重新建表即可.(此例中的数据库是test) alter dat ...
- php mysql 中文字段名_php mssql扩展SQL查询中文字段名解决方法
一.问题: 数据库是MS SQLServer2000,要把SQLServer2000里的一张表的数据导入MySQL5,其中SQLServer2000表的字段以简体中文命名(强烈建议不要以中文做为字段名 ...
- Mysql基础中篇[数据库的使用和数据查询]~
基本概念: 数据库: 英文单词DataBase,简称DB,按照一定格式存储数据的一些文件的组合,顾名思义:存储数据的仓库,实际上就是一堆文件,这些文件中存储了具有特定格式的数据. 数据库管理系统: D ...
- php与mysql手册下载地址_PHP与Mysql的连接
呼,搞了足足两天零12个小时05分17秒,恍然大悟,原来我把数据库的名字写错了,导致这两天零12个小05分17秒的时间,都在迷惘中度过,不过现在算是解决了,所来特来发下心得体会. 忠告:写程序切记马虎 ...
- PHP与MySQL连接菜鸟教程_PHP 连接 MySQL 数据库 | w3cschool菜鸟教程
PHP 连接 MySQL 数据库 使用 PHP mysqli_connect() 函数连接到一个 MySQL 数据库. 连接到一个 MySQL 数据库 在我们访问数据库中的数据之前,我们必须创建一个到 ...
- 按学号和姓名进行查询c语言,数据库实验4 数据查询(答案)
数据库技术与应用实验 实验4 数据查询 实验4 数据查询 学号:18103317 专业:电子信息工程 一.实验内容和步骤 1.在studentsdb数据库中,使用下列SQL语句将输出什么?并说明语句中 ...
- PHP中mysql如何添加记录_PHP向MySql提交数据添加记录的简单代码_PHP教程
今天有位站长咨询烈火一个特别简单的问题--如何使用PHP向Mysql添加记录?现在就把一个简单的存储数据的代码给出来,稍加几句分析,高手就不要看了,非常基础的例子. PHP向MySQL数据库中写入数据 ...
- php mysql 手机归属地_PHP手机号码归属地查询代码(API接口/mysql)_PHP教程
文章来介绍一下关于手机号码归属地实现方法,我们可以利用api接口与mysql+php来实例有需要的同学看看. 首先我们介绍使用自己的数据库查询多个手机号码,那还是建议你拥有一个自己的的手机号码数据库. ...
- php mysql 手机归属地_PHP手机号码归属地查询代码(API接口/mysql)
首先我们介绍使用自己的数据库查询多个手机号码,那还是建议你拥有一个自己的的手机号码数据库.正常情况下,只是满足一般查询的话,你不需要去购买专业版的手机号码数据库,增加无谓成本.我免费为你提供一个ACC ...
最新文章
- 简单介绍4种限流算法!(固定窗口计数器算法、滑动窗口计数器算法、漏桶算法、令牌桶算法)...
- Android开发究竟该如何学习,附架构师必备技术详解
- python读文件去除空行_「34」Python文件操作经典案例:CSV文件的读与写
- mysql的左连接应用
- 深井软岩巷道群支护技术与应用_引领支护创新,促进行业发展
- 工作171:阅读账号里面的新增调用接口操作
- Transformer太深不行?NUS字节发现注意力坍缩,提出重注意机制!
- -bash:fork:Resource temporarily unavailable
- 解决tomcat启动startup.bat一闪而…
- android audiorecord jni,Android AudioRecord初始化失败
- CentOS 7下安装QT5.8
- 联想计算机BIOS密码忘记了,联想笔记本CMOS(BIOS)密码清除
- Java观察者模式(Observer)
- R语言使用dcauchy函数生成柯西分布密度函数数据、使用plot函数可视化柯西分布密度函数数据(Cauchy distribution)
- godaddy 服务器位置,GoDaddy DNS服务器地址 | Godaddy美国主机中文指南
- 【R】【课程笔记】04+05 数据预处理+收益率计算
- onlyoffice-开源在线文档编辑软件
- Woo获得700万美元资金 并推出AI猎头
- 黑客是如何监控你的电脑的呢?今天来了解C++远程监控系统!
- [行为识别论文详解]TSN(Temporal Segment Networks)