在我维护的网站中,我需要两次查询同一个表(文章),每个类别的文章一次。 AFAIT基本上有两种方法可以做到这一点(也许有人可以提出更好的第三种方式?):
html
。HTML
。所以这就是:
$newsQuery = $mysqli->query("SELECT * FROM articles WHERE type='news' ");
while($newRow = $newsQuery->fetch_assoc()){
// generate article summary in html
}
// repeat for informational articles
vs this:
$query = $mysqli->query("SELECT * FROM articles ");
$news = Array();
$info = Array();
while($row = $query->fetch_assoc()){
if($row['type'] == "news"){
$news[] = $row;
}else{
$info[] = $row;
}
}
// iterate over each array separate to generate article summaries
记录集不是很大,当前< 200并且可能会增长到1000-2000。两种方法之间的时间是否存在显着差异,如果是这样,哪一种更快?
(我知道这整个事情看起来非常低效,但它是一个编码不好的网站,我继承并且必须在没有预算的情况下处理重构整个事情......)
我用PHP编写,没有框架:(,在MySql db上。
我刚刚意识到我遗漏了一个主要细节。在网站的给定页面上,我们将一次显示(并因此从数据库中检索)不超过30条记录 - 但这里有捕获:15篇信息文章和15篇新闻文章。在每个页面上,我们会拉出下一个15种。
答案 0 :(得分:1)
你知道你可以在数据库中排序吗?
SELECT * FROM articles ORDER BY type
答案 1 :(得分:1)
修改强>
由于对问题所做的更改,我正在更新我的答案,以解决新发布的要求:“新闻”15行,“非新闻”15行。
问题的要点是相同的“哪个更快......一个查询到两个单独的查询”。答案的要点保持不变:每个数据库往返都会产生开销(额外的时间,尤其是通过网络连接到单独的数据库服务器),所以在其他条件相同的情况下,减少数据库往返次数可以提高性能。
新要求确实不会对此产生影响。新发布的需求真正影响的是实际的查询以返回指定的结果集。
例如:
( SELECT n.*
FROM articles n
WHERE n.type='news'
LIMIT 15
)
UNION ALL
( SELECT o.*
FROM articles o
WHERE NOT (o.type<=>'news')
LIMIT 15
)
将该语句作为单个查询运行将需要更少的数据库资源,并且更快而不是运行两个单独的语句,并检索两个不同的结果集。
我们没有提供任何关于type
的其他值的指示,因此这里提供的语句只涉及两个一般类别的行:具有type='news'
的行和所有其他行对type
有其他价值。
该查询假定type
允许NULL值,并且我们想要返回类型为NULL的行。如果不是这样,我们可以将谓词调整为
WHERE o.type <> 'news'
或者,如果我们感兴趣的type
有特定值,我们可以在谓词中指定
WHERE o.type IN ('alert','info','weather')
如果需要“分页”......“接下来的15”,我们看到应用的典型模式,LIMIT 30,15
可能效率低下。但是这个问题并不是要求提高“分页”查询的效率,而是要求运行单个语句或运行两个单独的语句是否更快。
这个问题的答案仍然是一样的。
原始回答
每次数据库往返都有开销。就数据库性能而言,对于小型集合(如您所描述的),您最好使用单个数据库查询。
缺点是您正在获取所有这些行并实现数组。 (但是,看起来这就是你在任何一种情况下使用的方法。)
如果您在显示的两个选项之间进行选择,请使用单个查询。那会更快。
就不同的方法而言,它实际上取决于您对这些阵列的处理方式。
您实际上可以让数据库使用ORDER BY
子句以指定的顺序返回行。
首先获取所有'news'
行,然后是非'news'
的所有内容,您可以
ORDER BY type<=>'news' DESC
这是MySQL的缩写,符合ANSI标准:
ORDER BY CASE WHEN t.type = 'news' THEN 1 ELSE 0 END DESC
您可以在输出每一行时从光标中获取,而不是获取每一行并将其存储在数组中,例如。
while($row = $query->fetch_assoc()) {
echo "<br>Title: " . htmlspecialchars($row['title']);
echo "<br>byline: " . htmlspecialchars($row['byline']);
echo "<hr>";
}
答案 2 :(得分:0)
处理这种情况的最佳方法是亲自测试。你现在有多少记录并不重要。你可以模拟你喜欢的任何数量,这从来都不是问题。此外,1000-2000实际上是一小组数据。
我有点不明白你为什么要两次迭代所有记录。您不应该以任何方式检索查询中的所有记录,而只需要使用一小部分记录。在您管理文章的典型网站中,每页最多10条记录。任何用户都不会以一种您必须立即提取所有记录的方式浏览2000篇文章。利用分页和智能查询。
//分别迭代每个数组以生成文章摘要
这不是你的意思,但有些东西告诉我这些数据也应存储在数据库中。我真的希望你不会为每一个页面点击动态生成文章摘录。
对我而言,这听起来更像是一个糟糕的建筑设计而不是其他任何东西......
PS:我认为数据库数据的排序/排序/过滤应该在数据库服务器上完成,而不是在应用程序本身中完成。您可以通过执行单个查询来节省一些流量,但如果您一次传输过多数据,那么它将无法帮助您,但您仍然无法使用。