国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

PHP到MySQL數(shù)據(jù)查詢過程概述

Original 2016-11-10 14:03:04 386
abstrakt:本篇手記主要介紹了"PHP到MySQL數(shù)據(jù)查詢過程概述",主要涉及到方面的內(nèi)容,對于MySql感興趣的同學可以參考一下:HP層到MySQL層Php到sql組件層次如下圖所示:ext/mysqli和ext/mysql 是客戶端的擴展程序庫(庫函數(shù)) ,在客戶端腳本層面的擴展庫。 Mysqli庫是mysql庫的擴展版本,擴展版本增加了列版定(Bind Column)綁定。PDO (

本篇手記主要介紹了"PHP到MySQL數(shù)據(jù)查詢過程概述",主要涉及到方面的內(nèi)容,對于MySql感興趣的同學可以參考一下:

HP層到MySQL層

Php到sql組件層次如下圖所示:

7.jpg

ext/mysqli和ext/mysql 是客戶端的擴展程序庫(庫函數(shù)) ,在客戶端腳本層面的擴展庫。 Mysqli庫是mysql庫的擴展版本,擴展版本增加了列版定(Bind Column)綁定。PDO (PHP Data Object) 是另外一種面向數(shù)據(jù)對象的 擴展庫。這些擴展庫直接面向編程者,而它的底層實現(xiàn)是mysql連接引擎(如mysqlnd和libmysql )(參考 http://bbs.chinaunix.net/thread-3679393-1-1.html 、http://blog.csdn.net/treesky/article/details/7286098 )。

mysqlnd和libmysql 是PHP端(客戶端)的數(shù)據(jù)庫連接驅(qū)動引擎。libmysql 是通用的數(shù)據(jù)庫連接引擎,而mysqlnd是專屬PHP開發(fā)的連接引擎,從屬于Zend中。 當PHP通過調(diào)用擴展庫(ext/mysqli和ext/mysql)中的mysql_query() 函數(shù)進行數(shù)據(jù)庫查詢的時候,Zend引擎將通過mysql(mysqlnd和libmysql)查詢引擎向MySQL服務器發(fā)出查詢請求。

MySQL層的數(shù)據(jù)查詢

8.jpg

MySQL服務器接受到客戶端的查詢請求后,查詢執(zhí)行過程如上圖所示: 
1. 查詢緩存,如果命中則直接將結果集返回給到客戶端,否則進入步驟2 
2. 對SQL語句依次進行解析、預處理、查詢優(yōu)化等操作,最終生成查詢執(zhí)行計劃(select的查詢執(zhí)行計劃可以通過explain select 查看) 
3. MySQL服務端的查詢執(zhí)行引擎將依據(jù)查詢執(zhí)行計劃 調(diào)用存儲引擎對數(shù)據(jù)進行查詢。當SQL語句的最后一層關聯(lián)被執(zhí)行后,將產(chǎn)生查詢結果集 
4. 查詢結果集發(fā)送到客戶端,傳回的方式有兩種:MySQL服務端緩存結果集 或 不緩存,這個由參數(shù)SQL_BUFFER_RESULT設置。 并且,如果用戶設置了SQL_CACHE 那么本次的查詢的結果集的一份副本存儲于 查詢緩存 中(步驟1相關)。

SQL_CACHE參數(shù)的啟示: 
將復雜的(多個關聯(lián))查詢分解為多條簡單的查詢,因為 
1)簡單查詢的緩存命中搞、 
2)復雜查詢結果的緩存易失效(關聯(lián)太多表) 
3)簡單查詢鎖的持有率低

MySQL Server 到 PHP層

通信模式MySQL Server和客戶端的通信采用“半雙工通信”,意思是:客戶端和服務端只能有一個在讀,并且另外一個必須是寫。

優(yōu)點:協(xié)議簡單,客戶端和服務端的寫權限是互斥的

缺點:無法進行流量控制,一端開始發(fā)送消息,另一端要完整的接受這個消息后才能響應它。

啟示:服務端查詢后的結果集發(fā)送給客戶端,客戶端(客戶端的查詢引擎,例如mysqlnd)必須完整的接受。所以,如果只需要少數(shù)行,記得在sql語句添加使用limit,少用select *。

結果集回傳模式結果集回傳中,每一行記錄都通過 客戶端-服務器通信協(xié)議進行包裝,然后再交接給下層的tcp協(xié)議;當然,在tcp層,可以先緩存每行記錄的協(xié)議包,組成大包在發(fā)出(對應用層透明)。

MySQL服務端只有將結果集全部發(fā)送給客戶端后,才能釋放結果集所占用的buffer。

服務端緩存模式

9.jpg

客戶端命令: mysql_unbuffer_query(),在客戶端的sql驅(qū)動擴展(mysqlnd)中不設置結果集的緩存,所以在fecth_array_xxx從結果集中讀取一條記錄時,需要從服務端的緩沖區(qū)中讀取。

服務端無緩存模式

10.jpg客戶端命令: mysql_query(),在客戶端的sql驅(qū)動擴展(mysqlnd)中設置了buffer用于緩存服務端的結果集,所以在fecth_array_xxx從結果集中讀取一條記錄時,是直接從mysqlnd擴展的緩沖區(qū)中取得row。

小結

如果結果集很大: 服務端無緩存模式可以減少服務端的內(nèi)存壓力喲,但是占用客戶端的內(nèi)存。這樣只有看情況取舍了。

PHP層到用戶層

在客戶端,于服務端對接的是mysql擴展引擎(libmysql 或者 mysqlnd),而用戶層是通過擴展庫(ext/mysql 或 ext/mysqli)和mysql引擎進行交互(啟示就是調(diào)用引擎的api讀取結果集)。

引 擎libmysql 和 mysqlnd 的機制并不同,主要區(qū)別是mysqlnd是轉為php寫的,被編譯到zend內(nèi)部。而libmysql是通用的庫,zend需要調(diào)用該庫實現(xiàn)數(shù)據(jù)庫的連 接。在這種卻別下,mysqlnd和zend具有更好的粘合性,在數(shù)據(jù)傳輸?shù)接脩魧訒r,少了一層數(shù)據(jù)的拷貝。具體的架構區(qū)別如下圖所示。圖中,五角星表示 緩存 buffer。

11.jpg

ext/mysqli和ext/mysql 是客戶端的擴展程序庫(庫函數(shù)) : 在客戶端腳本層面mysqlInd和libmysql 是MySQL Server端的驅(qū)動程序。其中,libmysql是通用的MySQL查詢驅(qū)動程序,而mysqlnd是專為PHP設置的基于Zend引擎的SQL驅(qū)動,即mysqlnd的數(shù)據(jù)驅(qū)動動作需要經(jīng)過Zend和mysqlserver交互,而libmysql直接和mysqlserver交互的。

對比: 
ext/mysqli(或者ext/mysql)和libmysql的數(shù)據(jù)庫查詢中的過程為: 
1)mysqi向libmysql驅(qū)動發(fā)送查詢請求 
2)Libmysql執(zhí)行請求并得到結果集存儲域libmysql的buffers中 
3)Mysqli申請內(nèi)存:zval指定的一塊buffer 
4)Mysqii從libmysql拷貝結果集到zval指定的buffer中 
ext/mysqli(或者ext/mysql)和mysqlnd的數(shù)據(jù)庫查詢中的過程為: 
1) mysqi向mysqlnd驅(qū)動發(fā)送查詢請求 
2) mysqlnd驅(qū)動通過zend引擎執(zhí)行sql查詢,結果集的每一行由一個buffer存儲(各個buffer是分散的) 
3) Mysqlnd創(chuàng)建多個zval,并指向這些buffers

例如: 
在ext/mysql & libmysql 中,libmysql驅(qū)動執(zhí)行SQL語句后得到結果集Row1~Row3,然后ext/mysql將結果集拷貝到zend buffer中,之后mysqli_fetch_xxx函數(shù)從該區(qū)域內(nèi)存中讀取結果集中的內(nèi)容。 
在ext/mysqli & mysqlInd 中,mysqlnd 驅(qū)動執(zhí)行SQL語句得到結果集Row1~Row3,其中,每個row直接由zend的一個buffer存儲,并由一個zval指向??蛻舳送ㄟ^映射直接從 該內(nèi)存區(qū)域中讀取結果實現(xiàn)mysqli_fetch_xxx。

小結

mysqlnd和zend更具有粘合性,在sql查詢驅(qū)動中,mysqlnd通過zend引擎訪問數(shù)據(jù)庫,并直接將將結果存儲域zend的buffer中,相比libmysql驅(qū)動(獨立于zend),少了一次結果集緩存拷貝。


Versionshinweise

Beliebte Eintr?ge