您的位置:首页 > 数据库

非原创,看到以后发现自己在很多时候都忽略了这个问题一些基本的SQL优化

2012-08-16 10:55 513 查看
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、注意数据库函数的限制以及其性能
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐