原文 http://blog.csdn.net/guoxuepeng123/article/details/7849681
1、子查詢的用法
子查詢是一個 select 查詢,它嵌套在 SELECT、INSERT、UPDATE、DELETE
語句或其它子查詢中。任何允許使用運算式的地方都可以使用子查詢。子查詢可以使我們的編程靈活多樣,可以用來實現一些特殊的功能。但是在效能上,往往一個
不合適的子查詢用法會形成一個效能瓶頸。
A、NOT IN、NOT EXISTS的相互關聯的子查詢可以改用LEFT JOIN代替寫法。比如:
select pub_name
from publishers
where pub_id not in
(select pub_id
from titles
where type = 'business')
--可以改寫成:
select a.pub_name
from publishers a left join titles b
on b.type = 'business' and
a.pub_id=b. pub_id
where b.pub_id is null
select title
from titles
where not exists
(select title_id
from sales
where title_id = titles.title_id)
--可以改寫成:
select title
from titles left join sales
on sales.title_id = titles.title_id
where sales.title_id is null
B、 如果保證子查詢沒有重複 ,IN、EXISTS的相互關聯的子查詢可以用INNER JOIN 代替。比如:
select pub_name
from publishers
where pub_id in
(select pub_id
from titles
where type = 'business')
--可以改寫成:
select distinct a.pub_name
from publishers a inner join titles b
on b.type = 'business' and
a.pub_id=b. pub_id
C、IN的相互關聯的子查詢用EXISTS代替,比如
select pub_name
from publishers
where pub_id in
(select pub_id
from titles
where type = 'business')
--可以用下面語句代替:
select pub_name
from publishers
where exists
(select 1
from titles
where type = 'business' and
pub_id= publishers.pub_id)
D、不要用COUNT(*)的子查詢判斷是否存在記錄,最好用LEFT JOIN或者EXISTS,比如有人寫這樣的語句:
select job_desc from jobs
where (select count(*) from employee where job_id=jobs.job_id)=0
--應該改成:
select jobs.job_desc from jobs left join employee
on employee.job_id=jobs.job_id
where employee.emp_id is null
select job_desc from jobs
where (select count(*) from employee where job_id=jobs.job_id)<>0
--應該改成:
select job_desc from jobs
where exists (select 1 from employee where job_id=jobs.job_id)
作為程式員還應該注意:
1、注意、關心各表的資料量。
2、編碼過程和單元測試過程盡量用資料量較大的資料庫測試,最好能用實際資料測試。
3、每個SQL語句盡量簡單
4、不要頻繁更新有觸發器的表的資料
5、注意資料庫函數的限制以及其效能
1、子查詢的用法
子查詢是一個 select 查詢,它嵌套在 SELECT、INSERT、UPDATE、DELETE
語句或其它子查詢中。任何允許使用運算式的地方都可以使用子查詢。子查詢可以使我們的編程靈活多樣,可以用來實現一些特殊的功能。但是在效能上,往往一個
不合適的子查詢用法會形成一個效能瓶頸。
A、NOT IN、NOT EXISTS的相互關聯的子查詢可以改用LEFT JOIN代替寫法。比如:
select pub_name
from publishers
where pub_id not in
(select pub_id
from titles
where type = 'business')
--可以改寫成:
select a.pub_name
from publishers a left join titles b
on b.type = 'business' and
a.pub_id=b. pub_id
where b.pub_id is null
select title
from titles
where not exists
(select title_id
from sales
where title_id = titles.title_id)
--可以改寫成:
select title
from titles left join sales
on sales.title_id = titles.title_id
where sales.title_id is null
B、 如果保證子查詢沒有重複 ,IN、EXISTS的相互關聯的子查詢可以用INNER JOIN 代替。比如:
select pub_name
from publishers
where pub_id in
(select pub_id
from titles
where type = 'business')
--可以改寫成:
select distinct a.pub_name
from publishers a inner join titles b
on b.type = 'business' and
a.pub_id=b. pub_id
C、IN的相互關聯的子查詢用EXISTS代替,比如
select pub_name
from publishers
where pub_id in
(select pub_id
from titles
where type = 'business')
--可以用下面語句代替:
select pub_name
from publishers
where exists
(select 1
from titles
where type = 'business' and
pub_id= publishers.pub_id)
D、不要用COUNT(*)的子查詢判斷是否存在記錄,最好用LEFT JOIN或者EXISTS,比如有人寫這樣的語句:
select job_desc from jobs
where (select count(*) from employee where job_id=jobs.job_id)=0
--應該改成:
select jobs.job_desc from jobs left join employee
on employee.job_id=jobs.job_id
where employee.emp_id is null
select job_desc from jobs
where (select count(*) from employee where job_id=jobs.job_id)<>0
--應該改成:
select job_desc from jobs
where exists (select 1 from employee where job_id=jobs.job_id)
作為程式員還應該注意:
1、注意、關心各表的資料量。
2、編碼過程和單元測試過程盡量用資料量較大的資料庫測試,最好能用實際資料測試。
3、每個SQL語句盡量簡單
4、不要頻繁更新有觸發器的表的資料
5、注意資料庫函數的限制以及其效能