Heim >Backend-Entwicklung >PHP-Tutorial >等待响应时间 - php+mysql环境下正在等待localhost的响应这个病怎么治呢?

等待响应时间 - php+mysql环境下正在等待localhost的响应这个病怎么治呢?

WBOY
WBOYOriginal
2016-06-06 20:15:252638Durchsuche

本地安装的php和mysql环境,用localhost访问某页面,该页面只是一个简单的链接mysql数据库并按以下sql语句执行查询并echo出数据,其中还用到了一个网上很流行的分页函数,每页显示20条数据,总的数据库有进30万条数据。

<code>SELECT Id,col1,col2col3,col4,col5 FROM DBtable LIMIT 100,20;
</code>

这条语句在mysql任务窗口里面的执行时间只有0.01sec
但是要打开这个PHP页面却需要近1分钟时间,至少也要40秒。

打开页面时,一开始都在显示正在等待localhost的响应,然后就非常慢。

等地host文件我已经加了127.0.0.1 localhost

my.ini文件内容如下:
basedir = L:/develop/mysql-5.6.24-win32
datadir = L:/develop/TestMysqlData
character_set_server=utf8
character_set_client=utf8
bind-address = 127.0.0.1
max_connections=100

负责链接数据库的config.php的执行时间也很短:[config.php页面执行时间:0.0050408840179443 ]秒

<code><?php $stime22=microtime(true); 
$host="localhost";
$db_user="root";
$db_pass="123456";
$db_name="moive";
$timezone="Asia/Shanghai";

$link=mysql_connect($host,$db_user,$db_pass);
mysql_select_db($db_name,$link);
mysql_query("SET names UTF8");

header("Content-Type: text/html; charset=utf-8");
$etime22=microtime(true);//获取程序执行结束的时间
$total22=$etime22-$stime22;   //计算差值
echo "<br />[config.php页面执行时间:{$total22} ]秒";
?>
</code>

通过分析发现,该php页面中链接数据库后执行sql的时间长是罪魁祸首!!!![执行sql时间:54.735748052597 ]秒

<code><?php include_once("config.php");
require_once('page.class.php'); //分页类!!!
ini_set('max_execution_time','100');//防止出现PHP Fatal error:  Maximum execution time of 30 seconds
$showrow = 20; //一页显示的行数
$curpage = empty($_GET['page']) ? 1 : $_GET['page']; //当前的页,还应该处理非数字的情况
$url = "?page={page}"; //分页地址,如果有检索条件 ="?page={page}&q=".$_GET['q']
//开始计时
$stime=microtime(true); 

$sql = "SELECT Id,col1,col2col3,col4,col5 FROM DBtable LIMIT";
$total = mysql_num_rows(mysql_query($sql)); //记录总条数
if (!empty($_GET['page']) && $total != 0 && $curpage > ceil($total / $showrow))
    $curpage = ceil($total_rows / $showrow); //当前页数大于最后页数,取最后一页
//获取数据
$sql .= " LIMIT " . ($curpage - 1) * $showrow . ",$showrow;";
$query = mysql_query($sql);
$etime=microtime(true);//获取程序执行结束的时间
$total=$etime-$stime;   //计算差值
echo "<br>[执行sql时间:{$total} ]秒";
echo "<h1>[SQL:{$sql} ]</h1>";
?>
</code>

网上查了一些关于等待响应时间过长的解决办法,经过尝试也无效。。

请帮我分析分析是什么原因呢?我感觉主要是这个PHP等到mysql响应的时间很长,而实际执行sql语句的时间其实也是很快的,为什么会出现这种貌似找不到mysql的现象呢?
更多 0

回复内容:

本地安装的php和mysql环境,用localhost访问某页面,该页面只是一个简单的链接mysql数据库并按以下sql语句执行查询并echo出数据,其中还用到了一个网上很流行的分页函数,每页显示20条数据,总的数据库有进30万条数据。

<code>SELECT Id,col1,col2col3,col4,col5 FROM DBtable LIMIT 100,20;
</code>

这条语句在mysql任务窗口里面的执行时间只有0.01sec
但是要打开这个PHP页面却需要近1分钟时间,至少也要40秒。

打开页面时,一开始都在显示正在等待localhost的响应,然后就非常慢。

等地host文件我已经加了127.0.0.1 localhost

my.ini文件内容如下:
basedir = L:/develop/mysql-5.6.24-win32
datadir = L:/develop/TestMysqlData
character_set_server=utf8
character_set_client=utf8
bind-address = 127.0.0.1
max_connections=100

负责链接数据库的config.php的执行时间也很短:[config.php页面执行时间:0.0050408840179443 ]秒

<code><?php $stime22=microtime(true); 
$host="localhost";
$db_user="root";
$db_pass="123456";
$db_name="moive";
$timezone="Asia/Shanghai";

$link=mysql_connect($host,$db_user,$db_pass);
mysql_select_db($db_name,$link);
mysql_query("SET names UTF8");

header("Content-Type: text/html; charset=utf-8");
$etime22=microtime(true);//获取程序执行结束的时间
$total22=$etime22-$stime22;   //计算差值
echo "<br />[config.php页面执行时间:{$total22} ]秒";
?>
</code>

通过分析发现,该php页面中链接数据库后执行sql的时间长是罪魁祸首!!!![执行sql时间:54.735748052597 ]秒

<code><?php include_once("config.php");
require_once('page.class.php'); //分页类!!!
ini_set('max_execution_time','100');//防止出现PHP Fatal error:  Maximum execution time of 30 seconds
$showrow = 20; //一页显示的行数
$curpage = empty($_GET['page']) ? 1 : $_GET['page']; //当前的页,还应该处理非数字的情况
$url = "?page={page}"; //分页地址,如果有检索条件 ="?page={page}&q=".$_GET['q']
//开始计时
$stime=microtime(true); 

$sql = "SELECT Id,col1,col2col3,col4,col5 FROM DBtable LIMIT";
$total = mysql_num_rows(mysql_query($sql)); //记录总条数
if (!empty($_GET['page']) && $total != 0 && $curpage > ceil($total / $showrow))
    $curpage = ceil($total_rows / $showrow); //当前页数大于最后页数,取最后一页
//获取数据
$sql .= " LIMIT " . ($curpage - 1) * $showrow . ",$showrow;";
$query = mysql_query($sql);
$etime=microtime(true);//获取程序执行结束的时间
$total=$etime-$stime;   //计算差值
echo "<br>[执行sql时间:{$total} ]秒";
echo "<h1>[SQL:{$sql} ]</h1>";
?>
</code>

网上查了一些关于等待响应时间过长的解决办法,经过尝试也无效。。

请帮我分析分析是什么原因呢?我感觉主要是这个PHP等到mysql响应的时间很长,而实际执行sql语句的时间其实也是很快的,为什么会出现这种貌似找不到mysql的现象呢?
更多 0

Windows 上 PHP 连接 MySQL 响应慢的原因
原因:my.ini里配置了bind-address=127.0.0.1

<code><?php $start = microtime(true);
$mysqli = new mysqli('127.0.0.1', 'root', '', 'mysql'); //连接耗时仅为0.0025秒.
//$mysqli = new mysqli('localhost', 'root', '', 'mysql'); //连接耗时超过1秒,比正常慢了400倍.
echo microtime(true)-$start;
</code></code>

分析:
1.my.ini里配置bind-address=127.0.0.1时,Win7及其以上版本系统PHP用localhost连接MySQL耗时超过1秒,比用127.0.0.1连接慢了400倍.
2.my.ini里配置bind-address=::1或bind-address=localhost时,Win7及其以上版本系统PHP用localhost连接MySQL速度是正常的,但用127.0.0.1连接又不正常了.
3.去掉bind-address配置,则用localhost或127.0.0.1连接MySQL速度都是正常的.
4.因为hosts里localhost被解析到::1(IPv6)和127.0.0.1(IPv4),注释掉 ::1 localhost 用localhost访问速度就会变正常,但不推荐这样做.

把主机地址改成127.0.0.1好像就可以了

30万条记录并不是很多,所以首先建议你考虑使用索引对查询进行优化,这样应该可以提升效率。
另一方面,通过mysql_num_rows查询记录总数是极大的败笔,这首先就会导致所有的记录被加载到php这边,你的时间消耗在30万条记录从mysql传送到php上了,应该使用select count(*)。
同时,我认为select count(*) 也是很无聊的,相对来说页码超出范围是一个小概率事件,应该使用
select SQL_CALC_FOUND_ROWS ...
大致的逻辑如下:(我很久不直接调用mysql系列函数了,所以以下你还是当伪码看吧,估计会有错误)

<code>$sql = "select SQL_CALC_FOUND_ROWS Id,col1,col2col3,col4,col5 FROM DBtable limit $limit, $rows";
$data = mysql_query($sql);
if (mysql_num_rows($data)  0) {
        //说明有匹配的记录,但是当前的limit导致的没有取得数据
        //因此重新定义limit子句再次查询就行了
        ...
    }
} else {
    $rows = mysql_fetch_all($data);
}</code>

我想这样会快很多。
如果你的数据量非常大的时候要考虑分表了,因为如果数据非常多,统计有多少行符合条件会导致极大的开销。或者,比较消极的办法是把符合条件的记录数缓存起来,因为如果数据很多的时候通常也没有人会在意精确的数目了,这也是为什么有的应用(比如搜索引擎的匹配结果)为什么没有最后一页的原因,就是想算出这个数太费时间了,而且没有人会真正在意很多页之后的内容。

楼主说自己是新手,不太理解,所以补充如下

<code>$sql = "SELECT Id,col1,col2col3,col4,col5 FROM DBtable"; //这里后面的 LIMIT 去掉
$countSql = "SELECT COUNT(*) FROM DBtable"; //加上这句
$total = mysql_fetch_col(mysql_query($countSql)); //加上这句(这句你需要调试)
$total = mysql_num_rows(mysql_query($sql)); //记录总条数 //这句不要了
if (!empty($_GET['page']) && $total != 0 && $curpage > ceil($total / $showrow))
    $curpage = ceil($total_rows / $showrow); //当前页数大于最后页数,取最后一页
//获取数据</code>

就行了,应该能快很多

@incNick 谢谢你啊,神一样的存在。
还有一点问题,一会儿等你吃完午饭再帮我看一下好吗?

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn