什么更有效(速度/内存):连接或多个选择

时间:2012-03-07 10:10:33

标签: mysql sql rdbms

我有以下表格:

用户

userId|name

itemId|userId|description

我想要实现的目标:我想从数据库中读取所有用户及其项目(用户可以拥有多个项目)。所有这些数据我希望它存储在如下结构中:

User {
id
name
array<Item>
}

其中Item是

Item {
itemId
userId
description
}

我的第一个选择是调用SELECT * from users,向用户部分填充数组,然后为每个用户执行SELECT * from items where userId=wantedId并完成项目数组。

这种方法是否正确,或者我应该使用连接吗?

我不想使用连接的原因是我有很多冗余数据:

userId1|name1|ItemId11|description11
userId1|name1|ItemId12|description12
userId1|name1|ItemId13|description13
userId1|name1|ItemId14|description14
userId2|name2|ItemId21|description21
userId2|name2|ItemId22|description22
userId2|name2|ItemId23|description23
userId2|name2|ItemId24|description24

冗余我的意思是:userId1,name1userId2,name2

我的理由是否合理?

LATER EDIT:我在谈论效率时加入了标题速度或内存

3 个答案:

答案 0 :(得分:2)

您正在通过网络往返交换线路和RAM中的字节数。网络延迟通常是更大的问题,因为内存便宜且网络速度更快。随着第一个结果集的大小增加,情况变得更糟 - Google为"(n+1) query problem"

我更喜欢JOIN。不要使用SELECT *写出来;几乎在每种情况下都是一个坏主意。你应该精确拼出你想要的列。

答案 1 :(得分:1)

加入是最佳表现方式。减少开销,您可以使用关系索引。你可以测试..但我确信连接比多次选择更快和优化

答案 2 :(得分:1)

答案是:这取决于。

多个SELECT:

  • 如果您最终发出大量查询来填充说明,那么您必须考虑到最终会进行大量的数据库往返。

使用JOIN:

  • 是的,您将返回更多数据,但您只需要往返一次。

您已经提到过您将部分用户填充数组。你知道有多少用户需要提前填写,因为在这种情况下我会使用以下内容(我在这里使用Oracle):

select * 
  from item a,
      (select * from 
      (select * 
         from user 
        order by user_id) 
       where rownum < 10) b
 where a.user_id = b.user_id
 order by a.user_id

这将只返回前10个用户的所有项目(这样大部分工作都是在数据库本身完成的,而不是让所有用户都回来,丢弃除了前10个用户之外的所有用户......)