【问题标题】:Random results. Which way is faster SQL-query or a flat file?随机结果。哪种方式更快 SQL 查询或平面文件?
【发布时间】:2010-01-03 19:25:51
【问题描述】:

我需要从 MySQL 表中显示一些随机数据(1 行),性能对我来说非常重要。它不一定必须是绝对唯一且超级随机的数据,所以我有两种选择:

1) 查询数据库(我的表有 > 500 000 行);

2) 每周自动从 db 结果创建一个平面文本文件(或带有数组的 php 文件),例如 400-500 行并从中获取一些随机结果(可能使用 requre_once 或类似的东西那个)。

哪种方式更好/更快?

谢谢。

【问题讨论】:

标签: php mysql random


【解决方案1】:

查询数据库。

但不是通过查询

SELECT * FROM tablename ORDER BY rand() LIMIT 1

因为这会为每一行分配一个随机数,然后返回最大值。

相反,计算行数,然后在该值内获取一个随机数并返回该行

$numrows = mysql_num_rows();
$r = rand(0, $numrows-1);
$sql = "SELECT * FROM tablename LIMIT $r, 1";

【讨论】:

  • 请注意,使用 InnoDB 计算行数很慢。
  • 谢谢,我不知道。
  • mysql_num_rows() 返回结果集中的行数,而不是表中的行数。
【解决方案2】:

绝对不要使用许多人使用的技巧:

SELECT * FROM MyTable ORDER BY RAND() LIMIT 1;

该查询看起来很简单,但它肯定会成为性能杀手。

这可能是一个快速的解决方案:

SELECT * FROM MyTable WHERE id > RAND() * (SELECT MAX(*) FROM MyTable) LIMIT 1;

这有一些异常情况,例如更频繁地选择跟随间隙的行。但你说你要快,不准确。请注意,MAX()COUNT() 等聚合在使用 InnoDB 等事务表时速度较慢,而在使用 MyISAM 时速度较快。

【讨论】:

  • 我相信你的第二个查询会比你的第一个更慢,因为它会生成一个 rand 并计算表中每一行的值的数量
  • @Adam:你会这么认为,但实际上第二个查询更具可扩展性 - 请参阅:stackoverflow.com/questions/1823306/…
【解决方案3】:

如果您的表具有增量唯一 ID,则只需

SELECT * FROM table WHERE id = $r

使用 $r 您通过上述建议获得的唯一号码。

【讨论】:

    【解决方案4】:

    关于如何在本网站和 Google 上通过您的查询有效地获得随机结果的材料很多,因此应该注意您的“如何正确编写查询”问题。

    对于您的第二部分,如果您想要整个星期/天/小时的相同结果,那么您可以轻松编写一个 cronjob 来获取结果,将其写入文件,然后让您的应用程序从该文件中提取。下次 cronjob 运行时,它将覆盖旧版本的文件,为您的应用程序提供新结果。这个 cronjob 甚至可以生成您的 HTML(或其他)并将静态页面放入您的 Web 层次结构中,让您从 Web 服务器的缓存中受益。 Web 服务器的缓存应该可以解决磁盘与数据库 I/O 的问题,如果您的数据库通常处于高负载状态,最终可能会对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      • 2011-01-17
      • 2022-01-22
      • 2010-09-26
      • 2012-08-05
      • 1970-01-01
      相关资源
      最近更新 更多