mysqli_fetch_assoc()性能PHP5.4与PHP7.0
我有一个大型MySQL查询(1.8M行,25列),我需要从中创建二维数组(基于主键的内存表) 代码按预期工作,但在PHP7.0中创建$table需要很长时间 PHP7.0性能如此差的原因是什么?我的主要兴趣是mysqli 感谢您提供的任何见解-如果我能够修复性能,PHP7将为我节省大量内存 mysqli代码片段mysqli_fetch_assoc()性能PHP5.4与PHP7.0,php,mysql,performance,multidimensional-array,mysqli,Php,Mysql,Performance,Multidimensional Array,Mysqli,我有一个大型MySQL查询(1.8M行,25列),我需要从中创建二维数组(基于主键的内存表) 代码按预期工作,但在PHP7.0中创建$table需要很长时间 PHP7.0性能如此差的原因是什么?我的主要兴趣是mysqli 感谢您提供的任何见解-如果我能够修复性能,PHP7将为我节省大量内存 mysqli代码片段 $start = microtime(true); $vysledek = cluster::query("SELECT * FROM `table` WHERE 1"); $quer
$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";
$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";
mysqli结果
Deb 7 PHP 5.4 mysqlnd 5.0.101.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秒执行整个脚本
峰值内存使用率: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.87秒的速度获取100000行数据
在5.24秒内获得300000行
在10.97秒内获得500000行
在19.17秒内获得700000行
以29.96秒的速度获取了900000行数据
43.03s内的行数为1100000行
以58.48秒的速度获得了1300000条线路
以76.47秒的速度获得1500000行
以96.73秒的速度获得1700000行数据
线路以107.78秒的速度获得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.72秒内获得100000行数据
在15.7秒内获得300000行
在38.7s内获得500000行
以71.69秒的速度获得700000行数据
以114.8s的速度获取900000行数据
在168.18s内获得1100000行数据
以231.69秒的速度获得了1300000行数据
以305.36秒的速度获取1500000行数据
在389.05秒时,行数达到1700000行
以434.71秒的速度售出了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.63秒内,行数达到300000行
在29.02s内获得500000行
在49.21s内获得700000行
以74.56秒的速度获得900000行数据
以104.97秒的速度获取了1100000行数据
以140.03秒的速度获得1300000行数据
在180.42s内获得1500000行
以225.72秒的速度获得1700000行数据
在250.01秒内获得1800000条线路 PDO代码片段
$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";
$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";
PDO结果
Deb 7 PHP 5.4 mysqlnd 5.0.101.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';
所有系统在19秒+-1秒变化时的执行时间类似
基于以上观察,我认为PHP5.X是合理的,因为执行的工作比转储到文件要多一些
- 所有3台服务器都在同一台主机上(源服务器和两台测试服务器)
- 重复测试时,测试是一致的
- 内存中已经有类似的变量了,我需要把它做比较去掉进行测试,这与问题无关
- CPU是在100%的整个时间
- 两台服务器都有32G RAM,交换设置为1,目标是将其作为内存操作执行
- 测试服务器是专用的,没有其他运行
- php.ini在主要版本之间发生了变化,但与mysqli/PDO相关的所有选项似乎都是相同的
- 重新安装PHP7后,Deb8机器降级至PHP5.6,问题消失
- 在php.net-ID72736上报告了一个bug,因为我相信已经证明问题出在php中,而不是系统或任何其他配置中