Zmr*_*zka 19 php mysql performance mysqli multidimensional-array
我有大量的MySQL查询(1.8M行,25列),我需要从中创建二维数组(基于主键的内存表).
代码按预期工作,但$ table创建在PHP7.0中需要很长时间.
PHP7.0表现如此糟糕的原因是什么?我的主要兴趣在于mysqli.
感谢您的任何见解 - 如果我可以修复性能,PHP7会为我节省大量内存.
mysqli代码片段
$start = microtime(true);
$vysledek = cluster::query("SELECT * FROM `table` WHERE 1");
$query_time = (microtime(true) - $start);
$start_fetch = microtime(true);
while($zaznam = mysqli_fetch_assoc ( $vysledek )){
$fetch_time+= (microtime(true) - $start_fetch);
$start_assign = microtime(true);
$table[$zaznam['prikey']] = $zaznam;
$assign_time+= (microtime(true) - $start_assign);
$start_fetch = microtime(true);
}
$total_time+= (microtime(true) - $start);
echo round($assign_time, 2).' seconds to set the array values\n';
echo round($query_time, 2).' seconds to execute the query\n';
echo round($fetch_time, 2).' seconds to fetch data\n';
echo round($total_time, 2).' seconds to execute whole script\n';
echo "Peak Memory Usage:".round(memory_get_peak_usage(true)/(1024 * 1024), 2)." MB\n";
Run Code Online (Sandbox Code Playgroud)
mysqli的结果
Deb 7 PHP 5.4 mysqlnd 5.0.10
1.8秒设置数组值
8.37秒执行查询
13.49秒获取数据
24.42秒执行整个脚本
峰值内存使用情况:8426.75 MB
Deb 8 PHP 5.6 mysqlnd 5.0.11-dev
1.7秒设置数组值
8.58秒执行查询
12.55秒获取数据
23.6秒执行整个脚本
Peak Memory Usage:8426.75 MB
Deb 8 PHP 7.0 mysqlnd 5.0.12-dev
0.73秒设置数组值
8.63秒执行查询
126.71秒获取数据
136.46秒执行整个脚本
峰值内存使用情况:7394.27 MB
Deb 8 PHP 7.0 mysqlnd 5.0.12-dev扩展基准测试
我已经扩展了部分提取的基准测试,以报告每100k行,结果如下:
在1.87s中获取100000行在5.24s中
获取300000行在10.97s中
获取500000行在19.17s中
获取700000行在29.96s中
获取900000行在43.03s中
获取1100000行在58.48s中
获取1300000行在76.47s中
获取1500000
行获取的行在96.73s中的1700000行在107.78s中
获得了1800000
DEB8 PHP7.1.0-dev libclient 5.5.50
1.56秒设置数组值
8.38秒执行查询
456.52秒获取数据
467.68秒执行整个脚本
峰值内存使用率:8916 MB
DEB8 PHP7.1.0-dev libclient 5.5.50扩展基准测试
在2.72s中获取100000行在15.7s中
获取300000行在38.7s中
获取500000行在71.69s中
获取700000行在114.8s中
获取900000行在168.18s中
获取1100000行在231.69中
获取1300000行在305.36中
获取1500000
行获取的行389.05s中的1700000行在434.71s中
获得了1800000
DEB8 PHP7.1.0-dev mysqlnd 5.0.12-dev
1.51秒设置数组值
9.16秒执行查询
261.72秒获取数据
273.61秒执行整个脚本
峰值内存使用率:8984.27 MB
DEB8 PHP7.1.0-dev mysqlnd 5.0.12-dev扩展基准测试
在3.3s中获取100000行在13.63s中
获取300000行在29.02s中
获取500000行在49.21s中
获取700000行在74.56s中
获取900000行在104.97s中
获取1100000行在140.03s中
获取1300000行在180.42s中
获取1500000
行获取的行在225.72s中的1700000行在250.01s中
获得了1800000
PDO代码段
$start = microtime(true);
$sql = "SELECT * FROM `table` WHERE 1";
$vysledek = $dbh->query($sql, PDO::FETCH_ASSOC);
$query_time = (microtime(true) - $start);
$start_fetch = microtime(true);
foreach($vysledek as $zaznam){
$fetch_time+= (microtime(true) - $start_fetch);
$start_assign = microtime(true);
$table[$zaznam['prikey']] = $zaznam;
$assign_time+= (microtime(true) - $start_assign);
$start_fetch = microtime(true);
}
$total_time+= (microtime(true) - $start);
echo round($assign_time, 2).' seconds to set the array values\n';
echo round($query_time, 2).' seconds to execute the query\n';
echo round($fetch_time, 2).' seconds to fetch data\n';
echo round($total_time, 2).' seconds to execute whole script\n';
echo "Peak Memory Usage:".round(memory_get_peak_usage(true)/(1024 * 1024), 2)." MB\n";
Run Code Online (Sandbox Code Playgroud)
PDO结果
Deb 7 PHP 5.4 mysqlnd 5.0.10
1.85秒设置数组值
12.51秒执行查询
16.75秒获取数据
31.82秒执行整个脚本
峰值内存使用情况:11417.5 MB
Deb 8 PHP 5.6 mysqlnd 5.0.11-dev
1.75秒设置数组值
12.16秒执行查询
15.72秒获取数据
30.39秒执行整个脚本
峰值内存使用情况:11417.75 MB
Deb 8 PHP 7.0 mysqlnd 5.0.12-dev
0.71秒设置数组值
35.93秒执行查询
114.16秒获取数据
151.19秒执行整个脚本
峰值内存使用情况:6620.29 MB
基线比较代码
$start_query = microtime(true);
exec("mysql --user=foo --host=1.2.3.4 --password=bar -e'SELECT * FROM `profile`.`table`' > /tmp/out.csv");
$query_time = (microtime(true) - $start_query);
echo round($query_time, 2).' seconds to execute the query \n';
Run Code Online (Sandbox Code Playgroud)
所有系统的执行时间类似于19秒+ -1秒变化.
基于上述观察,我会说PHP 5.X是合理的,因为执行的工作比仅仅转储到文件要多一些.
在将PHP7重新安装回来后,Deb8机器被降级为PHP5.6并且问题消失了
在php.net上报告了一个错误 - ID 72736,因为我相信已证明问题出在PHP中,而不是在系统或任何其他配置中
编辑1:添加了PDO比较
编辑2:添加基准测试标记,编辑PDO结果,因为存在基准测试错误
编辑3:原始问题中的主要清理,重建代码snipets以更好地指示错误
编辑4:关于降级和升级PHP的补充点
编辑5:为DEB8 PHP7.0添加了扩展基准测试
编辑6:包含php7配置
编辑7:PHP 7.1 dev的性能测量与两个库 - 使用来自bishop的配置编译,删除了我的php-config
编辑8:添加了与CLI命令,次要清理的比较
供交叉参考:随着2016 年 12 月 1 日PHP 7.1的发布,这个问题应该得到解决(在 PHP 7.1 中)。
PHP 7.0:即使在票证中写着 PHP-7.0 已被修补,我还没有在最近的更改日志(2016 年 11 月 10 日的 7.0.13,自补丁合并日期以来)中看到这是当前的一部分PHP 7.0.x 版本。也许在下一个版本中。
该错误已在上游跟踪(感谢 OP 的报告):Bug #72736 - 使用 mysqli / PDO 获取大型数据集时性能缓慢(bugs.php.net;2016 年 8 月)。
| 归档时间: |
|
| 查看次数: |
1412 次 |
| 最近记录: |