从mySQL db显示单个值的更有效方法?

时间:2011-03-30 14:17:33

标签: php mysql random

我到目前为止只是在学习PHP并喜欢它。我有这个代码从数据库中提取一个随机ID,但我知道如何做的唯一方法是使用while循环,这似乎不是很有效。任何人都可以告诉我如何调整这些代码?正如您所看到的,我只是尝试从$ DB中为$ pollquestionid分配一个随机的活动ID。

///this gets a random active poll number
    $sql12 = "SELECT id FROM poll WHERE removed = 0 AND active = 1 ORDER BY RAND() LIMIT 1";
    $result12 = mysql_query($sql12);
    while ($myrow12 = mysql_fetch_array($result12)) {
    $pollquestionid = $myrow12['id'];
    }

提前致谢!

4 个答案:

答案 0 :(得分:1)

我认为当你循环播放它时,它不会那么重要,它不会增加任何性能提升,因为你限制了你的查询。

您可以尝试此功能:http://nl3.php.net/manual/en/function.mysql-fetch-row.php

当您尝试学习PHP时,PHP.net是一个很好的资源,查看“另请参阅”功能,当您想要做一些不同的事情时,它们可能会派上用场

$sql12 = "SELECT id FROM poll WHERE removed = 0 AND active = 1 ORDER BY RAND() LIMIT 1";
$result12 = mysql_query($sql12);
$row = mysql_fetch_row($result);
$randomid = $row[0];

答案 1 :(得分:1)

正如评论所说,代码真的没什么问题。我只想使用“if”而不是“while”,并将其留在那里。

答案 2 :(得分:1)

没有错 - 如果你将结果限制为1行(你是),那么你最多可以获得1行,因此你的while循环最多只运行一次。您可以使用if而不是while重写,但这在“毫无意义的微观优化”领域中非常重要:

if ($myrow12 = mysql_fetch_array($result12)) {
    $pollquestionid = $myrow12['id'];
}

主要问题实际上是在数据库服务器上:因为你的ORDER BY子句不能构建在任何索引上,它将1)将表排序到另一个临时表中(如果它足够大,则使用磁盘;磁盘访问是sloooooow),2)走顶行3)扔掉临时表。那里略微低效。 Milen Kostadinov提出了一个更有效的查询版本in the comments to MySQL documentation

SELECT id, col1, col2, ... , colN FROM tab 
  WHERE id IN (
    SELECT id FROM tab 
      WHERE conditions 
      ORDER BY RAND()
      LIMIT m
  )

首先,子查询运行会发生什么 - 只对数字ID进行排序(比整个表快得多),然后返回该组中的 m 并用于请求整个表中的相关行(也很快)。

答案 3 :(得分:1)

这个问题似乎很模糊,不可能分辨出你关注的是什么 - 对于while循环或真正存在的问题而言,这个问题可以忽略不计order by rand问题。

对于后者请使用搜索,https://stackoverflow.com/search?q=mysql+rand将为您提供几种解决方案。

对于前者,简短回答只是“不要使用”

$sql12 = "SELECT id FROM poll WHERE removed = 0 AND active = 1 ORDER BY RAND() LIMIT 1";
$result12 = mysql_query($sql12);
$myrow12 = mysql_fetch_array($result12);
$pollquestionid = $myrow12['id'];
然而,人们可以更深入地了解问题 事实上,我们摆脱了一条线但仍然有4.为什么不把它变成一条:

$poll_qid=dbgetvar("SELECT id FROM poll WHERE removed = 0 AND active = 1 ORDER BY RAND() LIMIT 1";)

使用用户定义的功能在代码缩短方面非常有效!
就像这个简单的功能:

function dbgetvar($query){
  $res = mysql_query($query);
  if (!$res) {
    trigger_error("dbget: ".mysql_error()." in ".$query);
    return FALSE;
  } else {
    $row = mysql_fetch_row($res);
    if (!$row) return NULL;
    return $row[0];
  }
}

会大大减少你的代码!
只需将它放入任何配置/库文件中,并在需要从SQL查询中单值输出时使用。

稍微改进一下,你可以使这个功能甚至支持某种占位符,在一些动态数据的情况下可以省去手动转义:

function dbgetvar(){
  $args  = func_get_args();
  $query = array_shift($args);
  foreach ($args as $key => $val) {
    $args[$key] = mysql_real_escape_string($val);
  }
  $query = str_replace("%s","'%s'",$query); 
  $query = vsprintf($query, $args);

  $res = mysql_query($query);
  if (!$res) {
    trigger_error("dbgetarr: ".mysql_error()." in ".$query);
    return FALSE;
  } else {
    $row = mysql_fetch_row($res);
    if (!$row) return NULL;
    return $row[0];
  }
}

所以,它可以这样使用

$name = dbgetvar("SELECT name FROM users WHERE id=%d",$_GET['id']);

$name = dbgetvar("SELECT id FROM users WHERE name=%s AND surname = %s",
                 $_GET['name'],
                 $_GET['surname']);

没有任何危险,可以省去手动逃逸。 这些标记被称为“占位符”,被认为是处理SQL查询的非常安全和有用的方法

当然,不仅可以使用这一个,而且可以使用整个函数族来获取单行,行数组或单个数组的数组......并最终将它们组合成类。

这叫做“编程”,Stackoverflow上的内容很少......

相关问题