日期:2014-05-17  浏览次数:20648 次

==============小白问题:SQL 优化=============
在看一本oracle database 11g sql的书。
知道你们有疑问了,为什么oracle的问题跑这来问?
我先回答,我觉得这个版块更活跃一些,高手更多一些,所以跑这来问了,原理应该是差不多的。
我看到书中其中一条建议
Use Table Joins Rather than Multiple Queries
即用表连接,而不用多条查询语句。
小白问题:我想当然是table joins就是要有join关键字的,但是是例子中给出的是没join关键字的。
(1)是不是没有join关键字,但是有下面例子中那样的where语句的也叫join?

-- GOOD (one query with a join)
SELECT p.name, pt.name
FROM products p, product_types pt
WHERE p.product_type_id = pt.product_type_id
AND p.product_id = 1;


--You should choose the join order in your query so that 
--you join fewer rows to tables later in
--the join order. For example, say you were joining three 
--related tables named tab1, tab2, and
--tab3. Assume tab1 contains 1,000 rows, tab2 100 rows, 
--and tab3 10 rows. You --should join
--tab1 with tab2 first, followed by tab2 and tab3.

上面是英文原文,我的理解是,如果有多个表要join,要先把大表join了,再join小表。
英文给出了文字例子(假如有tab1 1000条记录,tab2 100条记录,tab3 10条记录,则要先join tab1 和 tab2,然后再tab2和tab3 join),但没给代码
所以,我有下面两个问题
(2)上面提到的例子,sql语句是不是应该像下面这么写?

SELECT a.name, b.name, c.name
FROM tab1 a, tab2 b, tab3 c,
WHERE a.id = b.id AND b.id = c.id
AND a.id = 1;

(3)为什么大表要先join?然后再join小表?

------解决方案--------------------
1. from 后面跟1个以上的表格就是join,会根据主键join表格中所有内容,然后根据where中的条件,撇去不符合的数据。在join的时候会产生大量无用数据,导致性能大大降低。

那就应该写成:
SELECT p.name, pt.name
FROM products p
inner join product_types pt on p.product_type_id = pt.product_type_id 
AND p.product_id = 1; 

2. 大表先join也多少有点道理,因为这样可以使用尽可能小的两个集合,先撇去无用数据
------解决方案--------------------
1楼说的已经很清楚了,from多个表加where条件实质也是join,只是写法不同,楼主应该注意的是其他join方式,例如 left join , right join , cross join 等。
------解决方案--------------------
Use Table Joins Rather than Multiple Queries
这个意思是建议使用多表连接,而不是多个查询语句的意思吧

oracle的连接方式和jion类似的,和sql2000是的语法是类似的
使用的where 中的=, (+)=, =(+)
------解决方案--------------------
(1)是不是没有join关键字,但是有下面例子中那样的where语句的也叫join?
答:a表 from inner join b表 on a.xx=b.xx 与from a,b where a.xx=b.xx从原理上没有差异。

(3)为什么大表要先join?然后再join小表? 
答:这个我倒有所保留,没有绝对的先如何再如何,如果非要用绝对两个字,那么绝对是要考虑如何尽快地把数据量减下来,所以有时候先join小表也不一定就不好。