基於以下系列討論內容的一大串源碼追蹤。以印證討論內容。
Remember this: Open your mind, use the source.
基於以下系列討論內容的一大串源碼追蹤。以印證討論內容。
Remember this: Open your mind, use the source.
1.line: 1395-1400, context of mysql_query()
2.line: 1404-1409, context of mysql_unbuffered_query()
3.line: 1345-1359, context of php_mysql_do_query_general()
上面的源碼內容符合 PHP Manual, PHP Large result sets and summary tables 等文的解釋。當程序員透過 mysql_query() 查詢時,資料結果集(result set)會被儲存在 client (即PHP 這端)。而用 mysql_unbuffered_query() 時,則只會在 clinet 儲存 "current row"。
看完 PHP 的源碼,再看 MySQL 的部份,以進一步確認 MySQL 的源碼實際上是否符合前述解釋。
PHP 源碼顯示,PHP 的 mysql_query() 調用 MySQL C API 的 mysql_store_result(),mysql_unbuffered_query() 調用 MySQL C API 的 mysql_use_result()。故列示於下。
mysql_store_result()
mysql_store_result() reads the entire result of a query to the client, allocates a MYSQL_RES structure, and places the result into this structure.
在 client 端配置一個 MYSQL_RES 的結構體,並儲放資料結果於此結構中。
mysql_use_result()
mysql_use_result() initiates a result set retrieval but does not actually read the result set into the client like mysql_store_result() does. Instead, each row must be retrieved individually by making calls to mysql_fetch_row().
MYSQL_RES
This structure represents the result of a query that returns rows (SELECT, SHOW, DESCRIBE, EXPLAIN). The information returned from a query is called the result set in the remainder of this section.
接著我們看 MySQL 源碼以印證手冊說明。
MYSQL_RES 所包含的內容有二種情形。一種是 bufered, 另一種是 unbuffered 。剛好對應 mysql_store_result(), mysql_use_result() 的儲存策略。
繼續觀察 mysql_store_result() 的源碼內容。
源碼內容顯示 mysql_store_result() 會註記資料結果為 "buffered",並清除 "unbuffered" 策略的相關內容。藉由函數指標 read_rows 調用 cli_read_rows() ,將資料結果集讀取至 client 。
在前一系列的討論中,我們的出發點是 CakePHP 的資料庫存取行為,因為 CakePHP 使用的是 mysql_query(),而非 mysql_unbuffered_query(),所以我們對資料結果集的記憶體配置方式,也是針對 mysql_query()。事實上,絕大多數的案例中, PHP 程序員使用的都是 mysql_query() 而非 mysql_unbuffered_query()。
我在稍後的回應中也說明,PHP 的 MySQL 函數,可以區分2種儲存策略 (即mysql_query() 與 mysql_unbuffered_query())。不過 FIEND 顯然忽視這點,隻字未提mysql_unbuffered_query(),始終堅持他的認知: "資料結果應該是儲存在 DB 端"。亦即他認為只有一種策略。
Ok, 也許資料庫管理與規劃書籍介紹的策略只有一種,但那是通則、是理論。但此處討論的卻是 PHP 查詢 MySQL 的實例。我說明的內容,並不是我的個人認知,而是程式碼明擺著的事實。如果 FIEND 還要說誰的 DB觀念不好,在誤導別人,請去對 PHP 和 MySQL 的開發團隊說吧。
