【问题标题】:How to Speed Up PHP Script With Huge MySQL Database如何使用庞大的 MySQL 数据库加速 PHP 脚本
【发布时间】:2012-11-25 06:27:14
【问题描述】:

我一直在努力设置 RSS 提要,并在这里的一些人的帮助下完成了它。但是,我确实需要一些更有经验的编码人员的建议,向我展示需要更改哪些内容才能保持相同的功能但加快页面加载速度。

它查看 30 个 RSS 项目并从我的 MySQL 数据库中获取 URL。问题是它从该表的 1 亿多行中随机选择 30 行。那是它应该做的,但是由于表格中有这么多行,这真的减慢了脚本的速度,我需要帮助!

<?php header("Content-type: text/xml"); ?>
<?php echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; ?>
<?php include('directory/database.php'); ?>
<rss version="2.0">
<channel>
  <title>Website Reviews</title>
  <link>http://www.mywebsite.com</link>
  <description>Professional Services</description>
  <pubDate><?echo date('Y/m/d H:i:s');?></pubDate>

<?php
    foreach( range( 1, 30 ) as $i ):
$number = mt_rand( 1, 141754641 );
$query="SELECT * FROM `list` LIMIT $number , 1";
$result = mysql_query($query);
if($result == false)
{
   user_error("Query failed: " . mysql_error() . "<br />\n$query");
}
elseif(mysql_num_rows($result) == 0)
{
   echo "<p>Sorry, we're updating this section of our website right now!</p>\n";
}
else
{
   while($query_row = mysql_fetch_assoc($result))
   {
      foreach($query_row as $key => $domain)
      {
         echo "$value";
      }
   }
}  
?>
<item>
    <title><?php echo $domain; ?> REVIEW</title>
    <pubDate><?echo date('Y/m/d H:i:s');?></pubDate>
    <link>http://www.mywebsite.com/review/<?php echo $domain; ?></link>
    <description>Looking for a review on <?php echo $domain; ?>?  We've got it!</description>
</item>
<?php endforeach; ?>

</channel>
</rss>

提前感谢任何人都可以提供的任何帮助!

【问题讨论】:

  • 查询执行需要多长时间?
  • 我猜选择 ORDER BY RAND() LIMIT 30 太慢了?
  • 我测试了几次,每次都超过5分钟,不过一般都超过10分钟。由于它是一个 RSS 提要,显然它需要更快地加载,我只是不知道如何优化它以便更快地从数据库中获取信息。
  • 我试过ORDER BY RAND() LIMIT 30,但似乎也没有加快速度:/
  • @popnoodles: ORDER BY RAND() 是一个非常糟糕的主意。见alternatives to ORDER BY RAND()

标签: php mysql xml performance rss


【解决方案1】:

Limit 必须进行表扫描,因此您要做的就是使用索引来发挥自己的优势。所以首先,让我们在名为“id”的表中添加一个自动增量 ID 字段。

那么,

<?php
$result = array();
$maxRow = mysql_fetch_assoc(mysql_query("SHOW TABLE STATUS LIKE 'list';"));
$max = $maxRow["Auto_increment"];
$minRow = mysql_fetch_assoc(mysql_query("SELECT id FROM 'list' LIMIT 1;"));
$min = $minRow["id"];
while (count($result) < 30) {
    $ids = array();
    while (count($ids) < 100) {
        $id = mt_rand($min, $max);
        $ids[$id] = 1;
    }
    $res = mysql_query("SELECT * from 'list' WHERE id IN (" . join(',', array_keys($ids)) . ") LIMIT 30");
    while (($row = mysql_fetch_assoc($result)) && (count($result) < 30)) {
        $result[] = array( ... ); // stuff results here
    }
}

// output
?>

【讨论】:

  • 旁注:随机 ID 可能无法获得完整的 30 行,所以我在这里检查并在需要时获取更多。
【解决方案2】:

您仍然可以一次选择全部 30 个。获取 30 条记录应该不会那么慢。

$numbers=array();
foreach( range( 1, 30 ) as $i ):
    $numbers[] = mt_rand( 1, 141754641 );
endforeach;

$query="SELECT * FROM `list` WHERE `whatever_primary_key_is` IN (".implode(',', $numbers).")";

【讨论】:

    【解决方案3】:

    我可以建议一个更强大的方法。

    1. 您必须考虑到您要查找的号码可能不存在
    2. 只使用一个 MySql 查询通常更快

    基于url1url2

    您可以使用此 php 代码:

    <?php
    // Connecting, selecting database
       $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password') or die('Could not connect: ' . mysql_error());
       mysql_select_db('my_database') or die('Could not select database');
    
    $query = "SELECT `url`
              FROM `liste`
              ORDER BY RAND()
             LIMIT 30" ;
    
    $result = mysql_query($query);
    
    if($result == false)
    {
       user_error("Query failed: " . mysql_error() . "<br />\n$query");
    }
    elseif(mysql_num_rows($result) == 0)
    {
       echo "<p>Sorry, we're updating this section of our website right now!</p>\n";
    }
    else
    {  $query_row = array();
       while($query_row = mysql_fetch_assoc($result))
        { 
            echo $query_row['url']; // no need to do the extra foreach
         }
     }
    
    ?>
    

    值 mysql_host,mysql_user,mysql_password,my_database 应替换为您的连接。

    只要您的 title 表中有 30 行,就可以了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 2013-10-31
      • 2013-11-27
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      相关资源
      最近更新 更多