
比如:
select from a join b on a.x=b.x left join c on a.x=c.x
还是
select id from a
程序获取ids
select b where id in (ids)
select c where id in (ids)
1 lightening 2015-06-04 05:16:52 +08:00 连成一条。数据库和应用有时候不在一个机器上,网络延迟比较大。 |
2 cevincheung OP @lightening 一般都会在同一内网吧 |
3 lightening 2015-06-04 05:40:59 +08:00 @cevincheung 我们不是的。 |
4 CupTools 2015-06-04 05:42:56 +08:00 连表,有时还会连4表查。 这是我上课的时候其中一条SQL: SELECT Count(*) AS S_NAMEOfCount, supplier.s_nationkey, nation.n_name FROM (SELECT DISTINCT supplier.s_name, supplier.s_nationkey, nation.n_name FROM (region INNER JOIN ((customers ey = = orders.o_custkey) gionkey) INNER JOIN nation ON customers.c_nationk nation.n_nationkey) INNER JOIN orders ON customers.c_custkey ON region.r_regiOnkey= nation.n_re INNER JOIN supplier ON nation.n_natiOnkey= supplier.s_n ationkey) GROUP BY supplier.s_nationkey, nation.n_name; |
5 Septembers 2015-06-04 05:51:15 +08:00 via Android |
6 F281M6Dh8DXpD1g2 2015-06-04 07:20:56 +08:00 三次查询的总时间肯定比一次的大吧 |
7 wy315700 2015-06-04 07:41:40 +08:00 分开查询何必用sql,用key value多好 |
8 zkd8907 2015-06-04 07:54:12 +08:00 @cevincheung 就算在内网上,网络IO成本也是比数据库服务器本地的IO成本要高的。。。(不要问我为什么知道的。。 |
10 mawenjian 2015-06-04 08:21:48 +08:00 分情况,强关联的表采用联表查询;如果关联性不是那么强的话,老老实实分步查,要不哪天拆库还得重写。 |
11 yangqi 2015-06-04 08:24:15 +08:00 只要索引什么的优化好,联表一次肯定比多次要快的 |
12 dai269619118 2015-06-04 08:46:01 +08:00 放数据里跑一下不就知道效率了吗 |
13 lucifer9 2015-06-04 08:48:53 +08:00 考虑到缓存的情况呢 |
14 caixiexin 2015-06-04 09:00:26 +08:00 数据库优化的一个原则就是查询次数越少越好,特殊的复杂sql语句除外。很多情况下网络开销,使用数据库链接都比劣质sql语句开销大。 |
15 lengxuecan 2015-06-04 09:13:48 +08:00 绝逼拆分写!没有之一! |
16 spkinger 2015-06-04 09:14:32 +08:00 不连表,用union把几个sql连起来试试 |
17 sujin190 2015-06-04 09:18:46 +08:00 如果数据有几百万你join一次试试 |
18 anyforever 2015-06-04 09:23:58 +08:00 @yangqi +1 关键是索引得优化好 |
19 jsuper 2015-06-04 09:38:44 +08:00 如果索引设计得好,两边关联的字段都有索引,那么关联是很快的。远比你分多次查询要来得快。 |
20 lzsadam 2015-06-04 10:25:54 +08:00 单表,遇到复杂的查询条件就跪了,代码维护起来累死 |
21 songw123 2015-06-04 10:47:56 +08:00 看情况,在实际环境中比较一下就行了,第一是速度,第二是数据库压力,第三是使用频度,选择最合适的就好,不过整体来说,很少用join了 |
22 lbp0200 2015-06-04 11:15:36 +08:00 如果数据库在内网,每次查询几百兆的数据,你就知道应该怎么做了。 |
23 zonghua 2015-06-04 11:41:05 +08:00 via iPhone a join b和where condition 有什么不同? |
25 yangqi 2015-06-04 12:23:06 +08:00 如果没办法优化关联索引那只能拆分查询了,不过说过了速度肯定没有优化过关联索引得快。 所以自己根据情况看着办吧 |
26 RemRain 2015-06-04 12:28:25 +08:00 如果 in 的集合不是特别大的话,习惯拆开来查询。前端扩容加机器就行;把各种处理和计算都压在数据库上的后果是,万一数据库抗不住,要扩容就吐血了 |
28 ivvei 2015-06-04 12:51:20 +08:00 楼主你这两种查询不等价。一个是横的,一个是竖的。 |
29 cevincheung OP |
30 pubby 2015-06-04 13:01:28 +08:00 @RemRain 同意 如果考虑到后期加入cache层的话,不join。 个人只在一些管理后台才会用复杂sql查询 另外 where in 在表上了百万级别后性能有问题 where in (1,2,3) 还不如 where id=1 union ... where id=2 union ... where id=3 快得多 当然list如果很长,需要另外想办法优化 |
31 cevincheung OP @pubby 为何我想到了exists :any |
32 sujin190 2015-06-04 13:40:18 +08:00 @ivvei 可是设计良好的话,单步的数据应该是非常小的,而且内网的话网络延迟应该在数毫秒内吧,就算单步十次也几十毫秒,而且相对来说是个稳定值 |
33 hylent 2015-06-04 17:29:55 +08:00 那么多join的话,基于主键的cache怎么用? 水平sharding之后,还怎么join? 每次查询几百兆的数据,这是在做啥么……,反正肯定不是web了吧? |
34 cevincheung OP @hylent so,你更倾向后者么? |
35 hylent 2015-06-04 17:45:28 +08:00 |
36 ivvei 2015-06-05 11:55:22 +08:00 @sujin190 比如 select * from a join b on a.aid = b.bid. 拆成两步就是 select * from a 和 select * from b。 原本返回的结果集是交集,现在需要把两表的数据都传回来。这个数据量明显是增大了很多的。返回来之后还没完,你还得在本地再进行人肉匹配,找一种算法来把两次返回的内容中相同的部分找出来。 除非考虑对前端进行水平扩展降低数据库单点压力,我没看到使用单步的方式有多大好处。 |
37 cevincheung OP @ivvei ids = select b_id from b where condition xxxxx data = select a_field from a where ids in (ids) 如果仅仅是select没有条件检索那肯定前者更好的 |
38 bash99 2015-06-05 16:40:22 +08:00 觉得第二种快的基本上是带排序之后,只需要TOP N结果的吧。 正常情况下第一种肯定比第二种快。 |
39 ivvei 2015-06-09 19:40:19 +08:00 @cevincheung 即便是带有条件的,你先查出id再查data,一样要多来回传一份id的数据。另外你修改了查询的内容。原本我举的例子里,所需要的data包含a,b两个表的数据。你现在这种情形只有表a的数据了。像这样的句子,你直接写 select a_field from a where ids in (select b_id from b where condition xxxxx) 也已足够,数据库的优化引擎选择的查询算法只会做得比你更好不会做得比你更差。 |
40 ivvei 2015-06-09 19:42:16 +08:00 @cevincheung one more thing, 有些数据库里, in 后面直接接 (id1,id2,id3...) 是有个数限制的。比如Oracle…… 限定1000个。超过1000就会出问题。而接一个子查询就没问题。 |
41 ben548 2015-12-02 17:19:32 +08:00 其实我也很好奇,不过这里的讨论好像没有给出一个很明确的答案,我在工作中为了避免写复杂的 sql 语句,通常使用第二种方式,不过个人感觉第二种查询方式比较慢啊 |