我有一个名为 orders 的表。订单上的一列是 customer_id
我有一个名为 customers 的表,有 10 个字段
鉴于这两个选项,如果我想构建一个订单对象数组并将客户对象嵌入到订单对象中,我有两个选择。
选项 1:
一个。首先查询订单表。 b.遍历记录并查询人员表以获取人员的记录
这会是这样的:
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:
一个。对所有字段进行连接
它是一个明显的#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 即使有良好的索引也很慢,您可能需要研究缓存。您可以在数据库(使用汇总表或物化/索引 View )、应用程序(如果有足够的 RAM)或专用缓存服务器(如 memcached)中进行缓存。当然,这取决于您的查询结果需要更新到什么程度。如果一切都必须完全是最新的,那么只要基础表更新,任何缓存都必须更新 - 它变得复杂并且变得不那么有用。
虽然这听起来像是一个报告查询,而且报告通常不需要是实时的。所以缓存也许能帮到你。
根据您的 DBMS,另一件需要考虑的事情是此查询对访问同一数据库的其他查询的影响。如果您的 DBMS 允许读取器阻止写入器,那么如果该查询需要很长时间才能运行,则该查询可能会阻止对表的更新。那会很糟糕。 Oracle 没有这个问题,SQL Server 在“读取已提交的快照”模式下运行时也没有。虽然我不知道 MySQL。
关于sql - 哪个提供更好的性能,一个大连接或多个查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1932019/