HP层到MySQL层
Php到sql组件层次如下图所示:
ext/mysqli和ext/mysql 是客户真个扩展程序库(库函数) ,在客户端脚本层面的扩展库。 Mysqli库是mysql库的扩展版本,扩展版本增加了列版定(Bind Column)绑定。PDO (PHP Data Object) 是其余一种面向数据工具的 扩展库。这些扩展库直接面向编程者,而它的底层实现是mysql连接引擎(如mysqlnd和libmysql )
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从结果集中读取一条记录时,须要从做事真个缓冲区中读取。
那么有很多同学在学习PHP到MySQL 的过程中难免会碰着很多困难,我为大家精心准备了相对应的教程,除了apache 和nginx这两个,还有大量框架和PHP中高等教程!
绝对可以让你学到赚到!
获取方法点击下方文章链接即可!
全套laravel框架、ThinkPHP框架全套教程分享,PHP程序员福利!
PHP开拓三年只懂增编削查?那是你没有方案好php学习路线
做事端无缓存模式
客户端命令: 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。
ext/mysqli和ext/mysql 是客户真个扩展程序库(库函数) : 在客户端脚本层面mysqlInd和libmysql 是MySQL Server真个驱动程序。个中,libmysql是通用的MySQL查询驱动程序,而mysqlnd是专为PHP设置的基于Zend引擎的SQL驱动,即mysqlnd的数据驱动动作须要经由Zend和mysqlserver交互,而libmysql直接和mysqlserver交互的。
比拟:
ext/mysqli(或者ext/mysql)和libmysql的数据库查询中的过程为:
1)mysqi向libmysql驱动发送查询要求
2)Libmysql实行要求并得到结果集存储域libmysql的buffers中
3)Mysqli申请内存:zval指定的一块buffer
4)Mysqii从libmysql拷贝结果集到zval指定的buffer中
ext/mysqli(或者ext/mysql)和mysqlnd的数据库查询中的过程为:
1) mysqi向mysqlnd驱动发送查询要求
2) mysqlnd驱动通过zend引擎实行sql查询,结果集的每一行由一个buffer存储(各个buffer是分散的)
3) Mysqlnd创建多个zval,并指向这些buffers
例如:
在ext/mysql & libmysql 中,libmysql驱动实行SQL语句后得到结果集Row1~Row3,然后ext/mysql将结果集拷贝到zend buffer中,之后mysqli_fetch_xxx函数从该区域内存中读取结果集中的内容。
在ext/mysqli & mysqlInd 中,mysqlnd 驱动实行SQL语句得到结果集Row1~Row3,个中,每个row直接由zend的一个buffer存储,并由一个zval指向。客户端通过映射直接从 该内存区域中读取结果实现mysqli_fetch_xxx。
小结
mysqlnd和zend更具有粘合性,在sql查询驱动中,mysqlnd通过zend引擎访问数据库,并直接将将结果存储域zend的buffer中,比较libmysql驱动(独立于zend),少了一次结果集缓存拷贝。