PHP 8.1.28 Released!


(PHP 4 >= 4.0.6, PHP 5)

mysql_unbuffered_query向 MySQL 发送 SQL 查询,无需获取和缓冲结果行


本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLiPDO_MySQL 扩展来替换之。参见 MySQL:选择 API 指南来获取更多信息。用以替代本函数的有:


mysql_unbuffered_query(string $query, resource $link_identifier = NULL): resource

mysql_unbuffered_query() 将 SQL query 发送到 MySQL,而不像 mysql_query() 那样自动获取和缓冲结果行。对于生成大型结果集的 SQL 查询,这可以节省大量内存,并且可以在检索第一行后立即开始处理结果集,因为不必等到执行完整的 SQL 查询。要在打开多个数据库连接时使用 mysql_unbuffered_query(),必须指定可选参数 link_identifier 来标识要使用哪个连接。



要执行的 SQL 查询。



MySQL 连接。如不指定连接标识,则使用由 mysql_connect() 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 mysql_connect() 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。


对于 SELECT、SHOW、DESCRIBE 或 EXPLAIN 语句,mysql_unbuffered_query() 在成功时返回 resource,错误时返回 false

对于其他类型的 SQL 语句,UPDATE、DELETE、DROP 等,mysql_unbuffered_query() 在成功时返回 true,在错误时返回 false



mysql_unbuffered_query() 的好处是有代价的:在获取所有行之前,不能对 mysql_unbuffered_query() 返回的结果集使用 mysql_num_rows()mysql_data_seek()。还必须使用相同的 link_identifier 从无缓冲的 SQL 查询中获取所有结果行,然后才能将新的 SQL 查询发送到 MySQL。


add a note

User Contributed Notes 5 notes

frappyjohn at dos2linux dot org
21 years ago
Don't let the two hands confuse you, these are both advantages (they should really be on the same hand):

On the one hand, this saves a considerable amount of memory with SQL queries that produce large result sets.

On the other hand, you can start working on the result set immediately ...
crazyone at crazycoders dot net
15 years ago
You are NOT required to read all rows from the resultset when using unbuffered query, you may opt out at any time and use mysql_free_result. Imagine looking at 1 million row when the first 50 suffice? Just free the result and you are good to go again.
post at jfl dot dk
20 years ago
If using optimized MyISAM tables I guess there is a big advantage with this function as it is possible to do selects and inserts on the same time as long as no rows in the table gets updated.
shaner at accretivetg dot com
20 years ago
Regarding bailing on a really large result, while doing an unbuffered query, there _is_ a way to do this: kill the thread and exit your processing loop. This, of course, requires having a separate database link. Something like below does the trick:

// a db link for queries
$lh = mysql_connect( 'server', 'uname', 'pword' );
// and a controller link
$clh = mysql_connect( 'server', 'uname', 'pword', true );

if (
mysql_select_db ( 'big_database', $lh ) )
$began = time();
$tout = 60 * 5; // five minute limit
$qry = "SELECT * FROM my_bigass_table";
$rh = mysql_unbuffered_query( $qry, $lh );
$thread = mysql_thread_id ( $lh );
while (
$res = mysql_fetch_row( $rh ) )
/* do what you need to do
* ...
* ...
if ( ( time() - $began ) > $tout )
// this is taking too long
mysql_query( "KILL $thread", $clh );
david at php dot net
21 years ago
You are absolutely required to retrieve all rows in the result set (option 'a' in the first comment). If you fail to do so, PHP will do so for you, and will emit a NOTICE warning you of the fact. From the MySQL API, "Furthermore, you must retrieve all the rows even if you determine in mid-retrieval that you've found the information you were looking for. ".

Also note that if you are using this function, you should be quick about processing the result set, or you will tie up the MySQL server (other threads will be unable to write to the tables you are reading from).

If you want to be able to 'abort' mid result-set or if you want to do lengthy processing on the results, you are misunderstanding the purpose of this function.

Also note that UPDATE queries etc return no result set, so this function is only useful for SELECT etc.
To Top