为什么这个PHP代码挂起调用mysql_query()?

时间:2009-08-26 23:42:11

标签: php mysql

我遇到这个PHP脚本时遇到问题

  

致命错误 /var/www/vhosts/richmondcondo411.com/httpdocs/places.php 77上超过了30秒的最长执行时间

代码挂在这里:

function getLocationsFromTable($table){

    $query = "SELECT * FROM `$table`";
    if( ! $queryResult = mysql_query($query)) return null;

    return mysql_fetch_array($queryResult, MYSQL_ASSOC);

}

和这里(到目前为止):

function hasCoordinates($houseNumber, $streetName){

    $query = "SELECT lat,lng FROM geocache WHERE House = '$houseNumber' AND StreetName = '$streetName'";
    $row = mysql_fetch_array(mysql_query($query), MYSQL_ASSOC);
    return ($row) ? true : false;

}

两者都在mysql_query()调用的行上。

我知道我为每个代码段使用不同的样式,这是因为我一直在玩第一个尝试隔离问题的人。

第一个例子中的$table是'school',它是一个肯定存在的表。 我只是不知道它为什么坐在那里等待超时而不是向我抛出错误。

来自网站其余部分的mysql查询正常运行。我试着确保我像这样连接

//connection was opened like this:
//$GLOBALS['dbh']=mysql_connect ($db_host, $db_user, $db_pswd) or die ('I cannot connect to the database because: ' . mysql_error());

if( ! $GLOBALS['dbh']) return null;

它让它过了那么好。有什么想法吗?

更新


这不是桌子的大小。我尝试只获得五个记录,但它仍然超时。另外,用这一行:

$query = "SELECT lat,lng FROM geocache WHERE House = '$houseNumber' AND StreetName = '$streetName'";

它只是寻找一个特定的记录,这就是它现在悬挂的地方。

6 个答案:

答案 0 :(得分:3)

听起来MySQL正在忙着将有效数据传回PHP,但是在Apache关闭PHP进程超过其最大执行时间之前,没有时间完成这个过程。

是否真的有必要从该表中选择所有内容?它有多少数据?是否有BLOBTEXT列可以解释特定延迟?

分析正在选择的内容以及您真正需要的内容将是一个很好的起点。

答案 1 :(得分:2)

等待mysql查询返回数据所花费的时间不计入执行时间。 See here.

问题很可能是代码中的其他地方 - 你所指责的函数可能在无限循环中被调用。尝试注释掉mysql代码,看看我是否正确。

答案 2 :(得分:1)

您的代码是否超时尝试连接或是否连接并挂起查询?

如果您的代码实际上超过了mysql_query调用(即使它必须等待很长时间才能超时),那么您可以使用mysql_error函数来确定发生了什么:

mysql_query("SELECT * FROM table");
echo mysql_errno($GLOBALS['dbh']) . ": " . mysql_error($GLOBALS['dbh']) . "\n";

然后,您可以使用错误编号来确定错误的详细原因:MySQL error codes

如果您的代码挂在查询上,您可以尝试在mysql命令行客户端中描述并运行查询,以查看它是否是数据大小问题。您还可以增加最长执行时间以允许查询完成并查看发生的情况:

ini_set('max_execution_time', 300); // Allow 5 minutes for execution

答案 3 :(得分:1)

我不知道您桌子的大小,但请尝试使用LIMIT 10并查看是否仍然挂起。

可能是您的表只是在一个查询中获取它。

答案 4 :(得分:1)

除非为hasQordinates()的参数$ houseNumber和$ streetName已经为MySQL查询清理(非常不可能),否则需要使用mysql_real_escape_string()来处理它们以防止(有意或无意)sql注入。要使mysql_real_escape_string()正常工作(例如,如果您通过mysql_set_charset更改了字符集),您还应该将MySQL连接资源传递给该函数。

error reporting是否设置为E_ALL,您是否查看了网络服务器的error.log(或设置了display_erorrs = On)?

试试这个

function hasCoordinates($houseNumber, $streetName) {
  $houseNumber = mysql_real_escape_string($houseNumber);
  $streetName = mysql_real_escape_string($streetName);
  $query = "
    EXPLAIN SELECT
      lat,lng
    FROM
      geocache
    WHERE
      House='$houseNumber'
      AND StreetName='$streetName'
  ";
  $result = mysql_query($query) or die(mysql_error());
  while ( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) {
    echo htmlspecialchars(join(' | ', $row)), "<br />\n";
  }
  die;
}

并参考http://dev.mysql.com/doc/refman/5.0/en/using-explain.html来解释输出。

答案 5 :(得分:1)

- 如果你把执行时间提高到300并且它仍然经历了300秒,我认为根据定义,你会得到类似无限循环的东西。

- 我首先怀疑是你的php代码,因为mysql用于处理大量数据集,所以一定要确保你实际上已经到达了有问题的mysql查询(在它之前死了,带有错误信息或其他东西)。

- 如果有效,那么尝试通过某些数据库gui或通过命令行访问数据库,使用数据库中的已知数据实际运行该查询,如果有的话,或者如果你没有用已知的好数字代替代码吨。

- 如果查询对它自己有效,那么我会检查来自$ houseNumber或$ streetName变量的意外sql注入,如VolkerK所述。