在重负载下检索mysql数据的正确方法

时间:2012-10-01 18:04:42

标签: php mysql

我使用PHP-MySQL构建了一个系统。该系统负载非常繁重,每分钟都有数千个选择,更新,插入和删除。

我想优化这个系统,使其更快,并减少服务器上的负载。 我已经介绍了memcache,但仍然需要mysql数据。

所以我的问题是,在这种情况下哪种方法最好。 目前我的查询看起来像这样:

$q = mysql_query($sql);
while(mysql_fetch_array($q)) {...

我已经读过使用mysql_fetch_assoc(?)

可以获得一点速度

但是当我开始优化这个系统时,或许有一种完全不同的方法?

谢谢大家 - (对我有限的英语技能道歉)

3 个答案:

答案 0 :(得分:1)

mysql_fetch_assoc vs mysql_fetch_array将复制较少的数据,因此使用较少的内存。由于数据以关联方式和数组中的index呈现,因此您将获得一些微小优化,但如果您的数据集很大则会有所帮助。

  • 尝试使用natural排序(AKA避免查询语句中的SORT)和LIMIT结果集(如果可以)
  • 批处理查询:相反,在同一个表上运行100个插入,尝试将其中的一些插入很小。
  • 缓存缓存缓存,如果可以:使用redis或memcached。
  • 如果您生成可被视为静态的网页,请尝试使用HTTP标头以避免浏览器始终请求您的网站
  • 等。等

答案 1 :(得分:1)

我建议你使用mysql关键字LIMIT来限制结果集。

为mysql返回的结果集添加分页将使您的应用程序更轻,ui将加载更快,因为要获取的行更少,并且mysql服务器将仅在需要时接收选择查询。 基本上这是如何使用限制的语法。

SELECT * FROM Person LIMIT X,Y

其中X是要检索的总行数,Y是偏移量。

示例:

SELECT * FROM Person LIMIT 10, 0

此查询将返回表Person的前十行,并且:

SELECT * FROM Person LIMIT 10, 10

将显示下一个10

答案 2 :(得分:0)

我一直在进行一些时序测试,涉及各种使用PHP从MySQL中获取信息的方法。目的是找到将数据列传输到简单数组的最快方法。我已经对enSEMBL数据库进行了测试,该数据库非常有用。

以下代码对于方法1至8(9个使用GROUP_CONCAT和10个使用PDO)是通用的:

$query = "SELECT DISTINCT `name` FROM species LIMIT 5000";
$result = $mysqli->query($query);
*Method code*
print_r(array_filter($species));

方法1:教科书方法

while ($row = $result->fetch_row()) {
         $species[] = $row[0];
      }

方法2:同时重置(注意,某些IDE在这里检测到错误)

while ($species[] = reset($result->fetch_row())) ;

方法3:foreach和重置

foreach ($result->fetch_all() as $value) $species[] = reset($value);

方法4:同时,foreach和重置

while ($species[] = $result->fetch_row()) ;
foreach ($species as $key => $value) $species[$key] = reset($value);

方法5:while和index

while ($row = $result->fetch_row()) $species[] = $row[0];

方法6:foreach和索引

foreach ($result->fetch_all() as $value) $species[] = $value[0];

方法7:递归数组

$species = call_user_func_array('array_merge', $result->fetch_all());

方法8:array_column

$species = array_column($result->fetch_all(), 0);

方法9:在查询中使用GROUP_CONCAT。

$species = explode(',', $result->fetch_row()[0]);

方法10:PDO

$species = $sth->fetchAll(PDO::FETCH_COLUMN, 0);

令人惊讶的是,方法1(教科书)的长度始终比实际上相同的方法5长约4倍,但与方法10(PDO)所花的时间大致相同。

方法2始终是最慢的方法,其长度要长50倍,大概是因为系统在某处写入警告。

方法4(两个循环)是第二慢的,花费了10倍的时间。

如上所述,方法1(教科书)和方法10(PDO)排在第三。

方法9的速度第四慢(时间长2倍,并且具有达到GROUP_CONCAT限制而没有任何警告的缺点)。

但是,最快的方法并不一致。从3、5、6、7和8中选择。

方法8(array_column)通常是最快的方法,但并非总是如此。但是,我认为这是最优雅的方法,并且提供了更多的灵活性,因为它可以使用查询选择的任何两列返回关联数组(但不要弄乱查询中的顺序!)