mysqli准备语句缓冲数据与无缓冲数据性能?

时间:2014-10-12 06:44:25

标签: php mysql mysqli prepared-statement

使用mysqli预处理语句在mysql中使用缓冲数据与未缓冲数据时,性能增加或减少了多少%。

1。缓冲数据。 e.g。

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

        if ($stmt = mysqli_prepare($link, $query)) {

        /* execute statement */
        mysqli_stmt_execute($stmt);

        /* bind result variables */
        mysqli_stmt_bind_result($stmt, $row['Name'], $row['CountryCode']);

        /* store result */
        mysqli_stmt_store_result($stmt);

        /* fetch values */
        while (mysqli_stmt_fetch($stmt)) {
            echo $row['Name'].'-'. $row['CountryCode'];
        }

        /* free result */
        mysqli_stmt_free_result($stmt);

        /* close statement */
        mysqli_stmt_close($stmt);
    }

/* close connection */
mysqli_close($link);    

2。无缓冲数据。 例如

$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";

        if ($stmt = mysqli_prepare($link, $query)) {

        /* execute statement */
        mysqli_stmt_execute($stmt);

        /* bind result variables */
        mysqli_stmt_bind_result($stmt, $row['Name'], $row['CountryCode']);

        /* fetch values */
        while (mysqli_stmt_fetch($stmt)) {
            echo $row['Name'].'-'. $row['CountryCode']);
        }

        /* close statement */
        mysqli_stmt_close($stmt);
    }

/* close connection */
mysqli_close($link);    

第一个例子使用

mysqli_stmt_store_result($stmt);

将结果数据存储在缓冲区中以便以后获取

而另一个示例直接将数据提取到客户端而不存储在缓冲区中。

  

您必须为每个查询调用mysqli_stmt_store_result()   成功生成结果集(SELECT,SHOW,DESCRIBE,EXPLAIN),   当且仅当您想缓冲完整的结果集时   客户端,以便后续的mysqli_stmt_fetch()调用返回   缓冲数据。

参考:http://php.net/manual/en/mysqli-stmt.store-result.php

所以我的问题是如果使用mysqli_stmt_store_result会增加多少效果?

2 个答案:

答案 0 :(得分:0)

我认为90%的时间你不会看到任何差异:

1-如果你有少量的数据,一切都会足够快,它不会产生太大的影响。

2-如果您有大量数据,这些数据将被放入缓冲区客户端,只有在您使用相同的结果集时才会节省时间。

不幸的是,我不能给你一个确定的答案,因为只有你知道查询将产生的数据量以及是否需要不止一次。

答案 1 :(得分:0)

虽然我从未需要存储结果,但我仍然觉得这个问题很有意思,并且想知道同样的事情。我已经在其中创建了一个包含垃圾数据的数据库,并针对它运行了一些测试,以查看使用无缓冲和缓冲结果的时序差异。我已经包括了我的测试和发现,以防它(或其他任何人)帮助你。

数据库设置

数据库由一个包含四个不同字段的表组成。这是架构:

ID          | int(5)    | primary_key, auto_increment
Name        | tinytext  | not_null
CountryCode | int(3)    | not_null
Description | tinytext  | not_null

该表有10,000多行,都有垃圾数据。 ID填充了自动增量值,CountryCode是11到999之间的随机数,最后两个字段NameDescription包含{{1}哈希的数值数据。

测试

总共进行了六次不同的测试。前5个测试是无缓冲和缓冲结果之间处理时间的比较。测试的总体目标是从表格的开头和中间看到不同大小的结果集的基准。最终测试仅是随机访问和顺序访问的缓冲结果的基准。无缓冲的结果不能通过md5任意进行,因此比较难以制定并被认为是公平的。

基准时间使用mysqli_stmt_data_seek()计算。 Tick在MySQLi语句准备之前就开始,并在语句关闭后立即结束。

以下是6项测试的细分:

  • 测试1:比较从表格的开头中选择的100行结果集的无缓冲/缓冲处理时间。
  • 测试2:比较从表格的中间中选择的100行结果集的无缓冲/缓冲处理时间。
  • 测试3:比较从表格的开头中选择的1000行结果集的无缓冲/缓冲处理时间。
  • 测试4:比较从表格的中间中选择的1000行结果集的无缓冲/缓冲处理时间。
  • 测试5:比较从表格的开头中选出的5000行结果集的无缓冲/缓冲处理时间,并重复三次。
  • 测试6: 10000行结果集的处理时间基准,随机访问,重复三次。

结果

PHP为上述测试产生了以下输出。

microtime()

结论

测试1-4表明大多数情况下性能增益可以忽略不计。即使在处理大量行或从表中的各种偏移量中获取记录时,缓冲结果的收益也很小。偏移位置增加了一些开销(大约百分之一秒来推进5000行)。

那就是说,缓冲仍然有它的位置。在测试五中,多次迭代具有几千行的结果集,使用缓冲结果有明显的好处。该测试的缓冲和非缓冲版本都有效处理15,000行。但是因为缓冲版本不必再次检索结果,所以它能够在不到一半的时间内完成它的工作。

正如其他人在这个问题中已经指出的那样,当必须随意/随机访问行时,缓冲非常有用。测试6简单地显示了可以随机访问缓冲的10,000行的长度,然后再重复两次。测试六有效地完全不按顺序提取30,000行。

当然,守则

以下是我用来创建此测试的代码。这一切都是程序性的,所以看起来并不是最漂亮的,但如果我发现自己正在制作一个类或修改代码来清理它,我一定会在这里更新它!

Test 1
Took 0.002000093460083 seconds to process unbuffered result of 100 rows from the beginning of the table
Took 0.0019998550415039 seconds to process buffered result of 100 rows from the beginning of the table


Test 2
Took 0.012001037597656 seconds to process unbuffered result of 100 rows from the middle of the table
Took 0.011001110076904 seconds to process buffered result of 100 rows from the middle of the table


Test 3
Took 0.013001918792725 seconds to process unbuffered result of 1000 rows from the beginning of the table
Took 0.012001037597656 seconds to process buffered result of 1000 rows from the beginning of the table


Test 4
Took 0.023001909255981 seconds to process unbuffered result of 1000 rows from the middle of the table
Took 0.020002126693726 seconds to process buffered result of 1000 rows from the middle of the table


Test 5
Took 0.19601988792419 seconds to process unbuffered result of 5000 rows sequentially, three times
Took 0.085008144378662 seconds to process buffered result of 5000 rows sequentially, three times


Test 6
Took 4.2634270191193 seconds to process buffered result of 10000 rows randomly, three times