mysql_result 对应mysqli哪个_mysql中的MYSQLI_USE_RESULT和MYSQLI_STORE_RESULT模式分析

之前都是使用同事封装好的mysql类,今天做性能测试时自己手动编写了查询mysql的操作。偶然发现mysqli::query(或者mysqli_query)有一个参数$resultmode取值为MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT。平时封装好的类中都是使用默认的MYSQLI_STORE_RESULT。Phpmanul上给出了这么一段话:

Either the constant MYSQLI_USE_RESULT or MYSQLI_STORE_RESULT depending on the desired behavior. By default, MYSQLI_STORE_RESULT is used.

If you use MYSQLI_USE_RESULT all subsequent calls will return error Commands out of sync unless you call mysqli_free_result().

下面又有人注释了这样一句:

/* If we have to retrieve large amount of data we use MYSQLI_USE_RESULT */

if ($result = mysqli_query($link, "SELECT * FROM City", MYSQLI_USE_RESULT)) {

/* Note, that we can't execute any functions which interact with the

server until result set was closed. All calls will return an

'out of sync' error */

if (!mysqli_query($link, "SET @a:='this will not work'")) {

printf("Error: %s\n", mysqli_error($link));

}

mysqli_free_result($result);

}

一下子激起了我的好奇心,这俩参数到底有什么区别呢?做个测试先。

$link = mysqli_connect("localhost", "userxx", "pwdxx", "dbtest");

if (mysqli_connect_errno()) {

printf("Connect failed: %s\n", mysqli_connect_error());

exit();

}

$quick = true;

$query_type = $quick ? MYSQLI_USE_RESULT : MYSQLI_STORE_RESULT;

$sql = "select * from tbl_xx";

$qrs = mysqli_query($link, $sql, $query_type);

/*先注释掉这段

$sql_ex = "delete from tbl_xx where xx";

$ret = mysqli_query($link,$sql_ex);

if (!$ret)

{

printf("Error:%s\n",mysqli_error($link));

}

*/

var_dump($qrs);

$rows =array();

while(($row= mysqli_fetch_array($qrs, MYSQLI_ASSOC))!=null)

{

$rows[]=$row;

}

mysqli_free_result($qrs);

mysqli_close($link);

?>

我们用quick开关控制这俩参数的选择;分别来看返回的结果集对象。

MYSQLI_USE_RESULT:

046e926b38fc9f3da0d4ed2a33dc0994.png

MYSQLI_STORE_RESULT:

3706e768fe84ec8e90b31fa883afc98d.png

看到没有,果然有区别,使用MYSQLI_USE_RESULT时返回的结果集对象的num_rows为0,而使用MYSQLI_STORE_RESULT时返回的结果集对象的num_rows为本次查询对应的实际行数。打开xdebug,再来看看执行时间:

8da05055671ddee3d6722cf538786878.png

上图左边使用MYSQLI_STORE_RESULT的两次统计结果,右边是使用MYSQLI_USE_RESULT的两次统计结果。实际上应该执行n次按平均值做对比,这里就偷懒了,仅各执行了两次。能够看出,右边的mysqli_fectch_array操作要比左边的多出30%-60%的时间。

结合上面两个统计结果,再google一通,这两个参数的区别可以总结为:

MYSQLI_USE_RESULT和MYSQLI_STORE_RESULT决定了mysqli client和server之间取结果集的方式。前者查询的时候并没有从server将结果集取回,后者查询时提取结果集返回给client,并分配内存,存储到用户程序空间中,之后mysqli_fetch_array()相当于是从本地取数据;而MYSQLI_USE_RESULT方式下,mysqli_fetch_array()每次都要向server请求结果行。

难怪phpmanual上那人注释说当检索大量数据时建议使用MYSQLI_USE_RESULT,因为MYSQLI_USE_RESULT有较低的内存需求,而MYSQLI_STORE_RESULT需要在client本地维护结果集,内存开销大。说到这里,可能会想,MYSQLI_USE_RESULT每次取数据时都要请求server,网络开销是不是要比MYSQLI_STORE_RESULT大呢?它节省的内存开销与带来的网络开销占比究竟如何,还需具体的测试数据来分析。

这两个参数背后的实际情况究竟怎样,还需要各路大神指点啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值