PHP/MySQL:大量SQL查询或几个较小的查询


PHP/MySQL: Massive SQL query or several smaller queries?

我这里有一个数据库设计,在简化版本中看起来是这样的:

building

  • 编号
  • 属性1
  • 属性2

其中的数据如下:

  • (1, 1, 1(
  • (2, 1, 2(
  • (3, 5, 4(

表格,attribute1_valuesattribute2_values,结构如下:

  • 编号
  • 价值

其中包含以下信息:

  • (1,"备选案文1的文字说明"(
  • (2,"备选案文2的案文说明"(
  • (6,"备选案文6的案文说明"(

我不确定这是否是最好的设置,但它是根据我的项目经理的要求完成的。它肯定有一定的道理,因为您现在可以轻松修改文本而不会弄乱 id 的。

但是现在我来到了一个需要列出属性的页面,那么我该怎么做呢?我看到两个主要选项:

1(进行一个大查询,从building收集所有值,同时从attribute{x}_values表中选择正确的文本表示形式。

2( 进行一个小查询,从building表中收集所有值。然后一次获取一个属性的文本表示。

选择

的最佳选择是什么?选项 1 是否比选项 2 更快?如果是这样,是否值得在维护方面花费额外的麻烦?

另一个建议是在服务器上创建一个视图,仅包含您需要的数据并从中查询。 这将使工作保持在服务器端,并且您每次都可以提取所需的内容。

如果你的属性

表中有少量的行,那么我建议先获取它们,全部获取! 将它们存储在某个数组中,使用 id 作为数组中的索引键。

然后你可以继续构建数据,现在你只需要使用各自的数组来查找属性值

我会推荐介于两者之间的东西。 在 php 中解析第一个表的结果,并计算出需要从每个属性 [x]_values 表中选择多少个属性。

然后,您可以使用每个表一个查询来批量选择属性,而不是每个属性一个查询或每个建筑物一个查询。

这是一个PHP解决方案:

$query = "SELECT * FROM building";
$result = mysqli_query(connection,$query);
$query = "SELECT * FROM attribute1_values";
$result2 = mysqli_query(connection,$query);
$query = "SELECT * FROM attribute2_values";
$result3 = mysqli_query(connection,$query);
$n = mysqli_num_rows($result);
for($i = 1; $n <= $i; $i++) {
    $row = mysqli_fetch_array($result);
    mysqli_data_seek($result2,$row['attribute1']-1);
    $row2 = mysqli_fetch_array($result2);
    $row2['value'] //Use this as the value for attribute one of this object.
    mysqli_data_seek($result3,$row['attribute2']-1);
    $row3 = mysqli_fetch_array($result3);
    $row3['value'] //Use this as the value for attribute one of this object.
}

请记住,此解决方案要求表attribute1_values和attribute2_values从 1 开始,每行增加 1。

Oracle/

Postgres/MySql DBA 这里:

多次运行查询会产生相当大的开销。数据库有多个往返,如果它在远程服务器上,这可能会加起来。数据库可能必须在MySql中多次解析相同的查询,如果有大量行,这将非常低效。现在,您的 PHP 方法(多个查询(的优势之一是它将使用更少的内存,因为它会在不再需要结果时释放结果(如果您将查询作为嵌套循环运行,但是如果您预先查询所有结果,您将有大量内存开销, 取决于桌子的大小(。

最佳结果是将其作为 1 个查询运行,一次获取 1 个结果,根据需要显示每个结果并丢弃它,这可能会对 MVC 框架造成严重破坏,除非您习惯于在视图中运行模型代码,或者运行小视图片段。

你的问题非常笼统,我认为要得到答案,你应该给出更多关于这个页面的外观和数据集有多大的提示。你会得到所有具有它们属性的建筑物,还是一次只有一个?因为您的数据结构看起来非常简单,并且除了树莓派之外的任何东西都可以很好地处理它。

如果你一次需要一条记录,你不需要任何特殊的技术,只需连接表。如果您需要列出所有建筑物并且想要节省数据库时间,则必须测量数据。如果你的属性比建筑物多,你必须选择一种方式,如果你有 8 个属性和 2000 个建筑物,你可以考虑在一个数组中缓存属性,为每个表选择一个,然后使用数组打印它们。我认为您不会在现代计算机上看到如此简单的表格的任何速度下降或改进。

$att1[1]='description1'
$att1[2]='description2'
....

切勿一次执行一个查询,尝试将它们组合成一个查询。

MySQL将缓存您的查询,并且运行速度会更快。PhP 循环比对数据库执行许多请求更快。

查询缓存将 SELECT 语句的文本与发送到客户端的相应结果一起存储。如果稍后收到相同的语句,服务器将从查询缓存中检索结果,而不是再次解析和执行该语句。

http://dev.mysql.com/doc/refman/5.1/en/query-cache.html