注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

phperwuhan的博客

记载一个phper的历程!phperwuhan.blog.163.com

 
 
 

日志

 
 

mysql中的MYSQLI_USE_RESULT和MYSQLI_STORE_RESULT模式分析  

2014-07-31 07:42:21|  分类: mysqli|pdo |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
来源:http://www.cnblogs.com/wangyonghui/archive/2013/04/24/3040824.html

之前都是使用同事封装好的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);

}

 

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

<?php

$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:

MYSQLI_STORE_RESULT:

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

上图左边使用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大呢?它节省的内 存开销与带来的网络开销占比究竟如何,还需具体的测试数据来分析。

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

  评论这张
 
阅读(273)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017