回答

收藏

一个大联接或多个查询哪个提供更好的性能?

技术问答 技术问答 413 人阅读 | 0 人回复 | 2023-09-14

我有一张叫订单的桌子。订单上的一列是customer_id,$ Q3 F; j1 ^3 e" |  r
我有一个名为“ customers”的表,具有10个字段" R) B, ^" {4 g& l* e* q
给定两个选项,如果我要建立一个订单对象数组并将其嵌入到一个客户对象中,那么我有两个选择。
, `2 T( [& n7 O7 z  C2 I选项1:+ _1 d- ^$ y+ H) v8 l
一种。首先查询订单表。b。遍历记录并查询人员表以获取人员的记录
( |9 S& Q. L7 d! u这将是这样的:/ U+ ?: ]: Z! D
Select * from APplications
% \( i# Y$ R) ~3 n+ t& I5 x7 ` Select * from Customer where id = 1
3 @9 ~% L. Q  ~3 s7 G5 I5 Y0 o0 M Select * from Customer where id = 2
- j, F; X+ S3 x; V Select * from Customer where id = 3
  ~% }: e& r1 v0 v1 T$ B0 h Select * from Customer where id = etc . . ., w6 ^& o9 D0 R5 Q
选项2:8 T4 a: f8 K5 y4 l! D, W2 v2 M
一种。在所有领域参加% b8 \, _" {: |; R
#2是显而易见的,因为您只执行一个查询,而不是1 + [numberOforders]个查询(可能是数百个或更多)0 j. P% d2 S7 n# _
就像这样:0 K9 L6 W" b/ \; f' F
Select * from Applications a, Customers c* T# t! o% W1 s( \; C
Innerjoin c.id = a.customerID
) t$ o& G& T1 I% O我的主要问题是,如果我还有10个其他订单表之外的其他表(类似于客户),而您在订单表中有ID,该怎么办?您应该执行一个将这10个表联接起来的查询,还是在某种程度上这样做效率低下:
) q* h" u6 S( S6 L4 e任何建议都将有所帮助..是否有任何优化来确保快速性能
& L/ T; x& R2 \0 {" Q# k$ m, {               
) O9 P( B) G: B% b( m4 `2 x* X解决方案:6 i2 K- S+ b9 O( s9 j) d
                7 y0 N- p& s. A; Y5 K& A

1 a3 n' z* s& \1 y* L+ I/ k3 Z' D* Q# \% j
                我同意每个人的观点,即即使有很多表,单联接也可能会更有效率。与在应用程序代码中完成工作相比,这也减少了开发工作量。假定表已正确索引,每个外键列上都有一个索引,并且(当然)每个主键列上都有一个索引。$ P) X4 _: J2 B- d9 d/ m2 ~8 {
最好的选择是首先尝试最简单的方法(大连接),然后查看其效果如何。如果运行良好,那就太好了-您已完成。如果执行不佳,请分析查询并查找表中缺少的索引。: k( ]+ ^( K6 Y7 i8 t; M
由于网络往返次数(如anijhaw所述),您的选择#1不太可能执行良好。有时这称为“选择N + 1”问题-
, I. I4 J$ ?, Q, H5 k# c6 s您执行一个SELECT以获得N个应用程序的列表,然后循环执行N
2 _7 v( S, i- Z1 X. VSELECTs以获取客户。对于应用程序程序员来说,这种一次记录循环是很自然的。但是当您一次处理整个数据集时,SQL的效果要好得多。
2 k- _  V0 X0 Y* v- o5 h如果即使索引良好,选项#2还是很慢,则您可能需要研究缓存。您可以在数据库中(使用摘要表或物化/索引视图),在应用程序中(如果有足够的RAM)或专用的缓存服务器(例如memcached)中进行缓存。当然,这取决于查询结果的最新程度。如果所有内容都必须是最新的,则每当底层表更新时,任何高速缓存都必须进行更新-
) j* K$ x( m8 T6 E9 ~, G2 w4 n它变得复杂并且变得不太有用。
/ y" ?+ N. X/ D/ Z' B5 c3 Z但是,这听起来像是报告查询,并且报告通常不需要实时。因此缓存可能可以为您提供帮助。; k; ?4 a! F6 R- U
根据您的DBMS,要考虑的另一件事是此查询对命中同一数据库的其他查询的影响。如果您的DBMS允许读取器阻止编写器,则此查询可能需要很长时间才能运行,因此可能阻止对表的更新。那将是不好的。Oracle没有此问题,在“读取已提交的快照”模式下运行时,SQL8 D9 p2 t! w) V8 M
Server也没有。我不了解MySQL。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则