程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> PHP到MySQL數據查詢過程概述

PHP到MySQL數據查詢過程概述

編輯:MySQL綜合教程

PHP到MySQL數據查詢過程概述


摘要

本文概述了從PHP層發起mysql查詢請求到mysql server 返回結果集的工作流程,並簡單描述了各層可能涉及到的動作和組件。從全局把握整個交互過程。

PHP層到MySQL層

Php到sql組件層次如下圖所示:
Zend->MySQL
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),少了一次結果集緩存拷貝。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved