author: selfimpr
blog: http://blog.csdn.net/lgg201
mail: [email protected]
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)基本屬性
- 結果集內存池
- 字段數(發送查詢時已得到)
- 是否二進制協議
- 字段元數據
- 將結果集對象作爲返回值返回
|