我有一张叫做订单的桌子.订单上的一列是customer_id
我有一个名为customers的表,有10个字段
给定两个选项如果我想构建一个订单对象数组并嵌入订单对象是客户对象,我有两个选择.
一个.第一个查询订单表.湾 循环记录并查询人员表以获取该人的记录
这将是这样的:
Select * from APplications Select * from Customer where id = 1 Select * from Customer where id = 2 Select * from Customer where id = 3 Select * from Customer where id = etc . . .
一个.在所有领域进行联接
它显然是#2,因为你只进行一次查询而不是1 + [numberOforders]查询(可能是数百或更多)
这将是这样的:
Select * from Applications a, Customers c Innerjoin c.id = a.customerID
我的主要问题是,如果我在订单表中有10个其他表(类似于客户),那么你在订单表中有了id.你应该做一个连接这10个表的单个查询,或者在某个时候这样做是否效率低:
任何建议都会有所帮助..是否有任何优化以确保快速性能
我同意所有人说过,即使有很多桌子,单个连接也可能更有效率.与在应用程序代码中完成工作相比,它的开发工作量也更少.这假设表被适当地索引,每个外键列上有一个索引,并且(当然)每个主键列上都有一个索引.
最好的办法是先尝试最简单的方法(大连接),看看它的表现如何.如果它表现良好,那么很棒 - 你已经完成了.如果它表现不佳,请对查询进行概要分析并查找表中缺少的索引.
由于网络往返次数(如anijhaw所述),您的选项#1不太可能表现良好.这有时被称为"选择N + 1"问题 - 您执行一个SELECT以获取N个应用程序的列表,然后在循环中执行N个SELECT以获取客户.对于应用程序员来说,这种一次性记录循环是很自然的; 但是当您一次操作整组数据时,SQL的效果会更好.
如果选项#2即使具有良好的索引也很慢,您可能需要查看缓存.您可以在应用程序中(如果有足够的RAM)或在专用缓存服务器(如memcached)中缓存数据库(使用摘要表或物化/索引视图).当然,这取决于您的查询结果需要的最新状态.如果所有内容都必须完全是最新的,那么每当更新基础表时,都必须更新任何缓存 - 它变得复杂并变得不那么有用.
这听起来像是一个报告查询,报告通常不需要是实时的.所以缓存可能能够帮助你.
根据您的DBMS,需要考虑的另一件事是此查询对其他查询到同一数据库的影响.如果您的DBMS允许读者阻止编写者,那么如果需要很长时间才能运行,则此查询可能会阻止对表的更新.那会很糟糕.Oracle没有这个问题,在"读取提交的快照"模式下运行时,SQL Server也没有.我不知道MySQL.
如果此customer_id在您的customer-table中是唯一的(并且其他ID在其他表中是唯一的),那么您的查询每个Application只返回1行,那么执行单个SELECT肯定更有效.
在一个查询中加入所有需要的客户将被优化,而使用大量单个SELECT则不能.
编辑
我用Oracle PL/SQL试用了50.000个应用程序和50.000个匹配客户.
在一个查询中选择所有内容的解决方案
0.172 s
在单个SELECT中选择每个客户的解决方案
1.984 s
对于其他客户或通过网络访问,这很可能会变得更糟.