我到目前为止只是在学习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'];
}
提前致谢!
答案 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上的内容很少......