不要让两只手让你困惑,这两者都是优点(它们应该真正放在同一只手上)
一方面,这对于产生大型结果集的 SQL 查询可以节省大量内存。
另一方面,您可以在检索到第一行后立即开始处理结果集 ...
(PHP 4 >= 4.0.6, PHP 5)
mysql_unbuffered_query — 发送 SQL 查询到 MySQL,不获取和缓存结果行
此扩展在 PHP 5.5.0 中已弃用,并在 PHP 7.0.0 中移除。应改用 MySQLi 或 PDO_MySQL 扩展。另请参见 MySQL:选择 API 指南。此函数的替代方案包括
mysql_unbuffered_query() 将 SQL 查询 query
发送到 MySQL,不自动获取和缓存结果行,如 mysql_query() 所做的那样。这对于产生大型结果集的 SQL 查询可以节省大量内存,并且您可以在检索到第一行后立即开始处理结果集,因为您不必等到完整的 SQL 查询完成。若要使用 mysql_unbuffered_query() 在打开多个数据库连接时,必须指定可选参数 link_identifier
来标识要使用的连接。
query
要执行的 SQL 查询。
查询中的数据应该 正确转义。
link_identifier
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(),直到所有行都被提取。您还必须从非缓存的 SQL 查询中提取所有结果行,然后才能使用相同的
link_identifier
向 MySQL 发送新的 SQL 查询。
不要让两只手让你困惑,这两者都是优点(它们应该真正放在同一只手上)
一方面,这对于产生大型结果集的 SQL 查询可以节省大量内存。
另一方面,您可以在检索到第一行后立即开始处理结果集 ...
使用非缓存查询时,您不必读取结果集中的所有行,您可以在任何时候选择退出并使用 mysql_free_result。想象一下,当只有前 50 行满足您的需求时,您需要查看 100 万行?只需释放结果,您就可以继续使用。
关于在进行非缓存查询时放弃非常大的结果,_确实_有一种方法可以做到:终止线程并退出处理循环。当然,这需要拥有一个独立的数据库链接。以下示例可以解决问题
<?php
// 用于查询的数据库链接
$lh = mysql_connect( 'server', 'uname', 'pword' );
// 和一个控制器链接
$clh = mysql_connect( 'server', 'uname', 'pword', true );
if ( mysql_select_db ( 'big_database', $lh ) )
{
$began = time();
$tout = 60 * 5; // 五分钟限制
$qry = "SELECT * FROM my_bigass_table";
$rh = mysql_unbuffered_query( $qry, $lh );
$thread = mysql_thread_id ( $lh );
while ( $res = mysql_fetch_row( $rh ) )
{
/* 执行您需要做的操作
* ...
* ...
*/
if ( ( time() - $began ) > $tout )
{
// 这花费的时间太长了
mysql_query( "KILL $thread", $clh );
break;
}
}
}
?>
您绝对需要检索结果集中的所有行(第一个注释中的选项“a”)。如果您未能这样做,PHP 将为您这样做,并发出一个 NOTICE 警告您。从 MySQL API 中,“此外,您必须检索所有行,即使您在检索过程中确定已经找到了您要查找的信息。”。
还要注意,如果您使用此函数,您应该尽快处理结果集,否则您将占用 MySQL 服务器(其他线程将无法写入您正在读取的表)。
如果您想在结果集中间“中止”或如果您想对结果进行长时间处理,那么您就误解了此函数的目的。
还要注意 UPDATE 查询等不会返回结果集,因此此函数仅对 SELECT 等有用。