原文
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、注意数据库函数的限制以及其性能