Sql 语句的优化 1 关于 sql 的语句分类 2sql 语句的执行顺序 3 说说 where 语句 4 关于子查询的巧用 5update  、 delete 和  insert  语句的技巧 6 关于关联的探讨   7 一些细节的东西
一、关于 sql 的语句分类 1.DDL 语句 用于建立各种数据库对象。(库、表、主键、外键、约束、索引。。。等) 2.DML 语句 insert  、 delete 、 update 3DCL 语句 各种权限控制语句
二、 sql 语句的执行顺序 执行顺序从右往左执行。 1. 插入语句  Insert into  table ( column1 ,  column12 ,。。。) values ( value1,value2,… )的执行也是如此。 2.Select  语句 select  字段列表  from table where  条件  group by  字段列表  having  条件  order by  字段 ( desc|asc ) 执行顺序:  where   group by ->having->order by ->select  列投影。 其中 where 的条件和 having 的条件是从右往左执行。 3.Update  table set  字段设置  where  条件 执行顺寻: where ->set->update Where  条件从右往左执行。 4delete from table where  条件 执行顺序: where- 》 delete Where  条件从右往左执行。 总结:执行中的性能消耗主要在 where 语句的查询。
三、说说 where 语句 3.1 执行顺序。(从右往左 ,尽量在右边条件过滤掉大部分行) 根据业务逻辑调整条件,可以提高效率。  如  where sex =' 男 '  and age >20  慢 where age >20 and sex =' 男 '  快 (因为按性别分可以一次过滤掉一半的行) 3.2 like  尽量少用。 like  语句进行模糊查询较慢。 3.3 between  and  不如  > <  快 where between 20 and 40;  慢 where age >20 and age <40;  快 3.4 in  和  exists delete from userinfo where userid in ( select userid from user_status );  慢 delete from userinfo A where exists ( select B.userid from user_status B where A.userid = B.userid );  快  ( 由于是 delete 语句难以 inner join)
四、关于子查询的巧用 4.1  in  语句和子查询性能的万恶之源 通信证的一个 sql 优化的例子: 我在原有的项目中找到如下代码:(将性能瓶颈进行标红) select U.USERID userid, U.MOBILE mobile, U.USERNAME username, U.USERTYPE userType, US.LOGIN_TIMES, US.LASTLOGIN_DT, US.FREE_DL free_dl,  UP.nickname nickname,   (case when us.modelid is null then 0 else us.modelid end) mobid , (select ml.MODEL_NAME from model_list ml where ml.modelid = US.MODELID) mobModel from USERINFO U, USER_STATUS US, USER_PROFILE UP   where U.USERID = US.USERID   and U.USERID = UP.USERID   AND (U.STATUS = 1 or U.STATUS = 2)    and (U.USERNAME =’zhanghe’)
原则一尽量使用系统函数 (case when us.modelid is null then 0 else us.modelid end) mobid  可以用标准函数替代 Nvl(us.modelid , 0 ) 原则二避免列映射里面用子查询。 (select ml.MODEL_NAME from model_list ml where ml.modelid = US.MODELID) mobModel  这部分可以放到关联中 原则三查询条件不要总是马后炮 from USERINFO U, USER_STATUS US, USER_PROFILE UP where U.USERID = US.USERID   and U.USERID = UP.USERID   AND (U.STATUS = 1 or U.STATUS = 2)    and (U.USERNAME =’zhanghe’) 这部分可以将特定表的查询提前。
最后我的优化语句为: ( 红色部分位修改 ) select U.USERID userid, U.MOBILE mobile, U.USERNAME username, U.USERTYPE userType, US.LOGIN_TIMES, US.LASTLOGIN_DT, US.FREE_DL free_dl,  UP.nickname nickname,   nvl(us.modelid,0) mobid , ml.MODEL_NAME mobModel from  ( select * USERINFO U where (U.STATUS = 1 or U.STATUS = 2 )and (U.USERNAME =’zhanghe’) inner join  USER_STATUS US on  U.USERID = US.USERID inner join  USER_PROFILE UP on U.USERID = UP.USERID left join  model_list ml on ml.modelid = US.MODELID
4.2 几乎所有的子查询都能变为表连接( 我已经把表优化到最烂。呵呵! ) 请看 Select  userid  ,  username ,  ( select logintime  from user_status where userid = u.userid ) logintime from  userinfo  u where userid in (  select userid from user_status where userid = u.userid )  where  ( userid = 1024 or userid = 1025 )  and sex = ‘ 男’  and username like ‘’ 张 %; 此语句是有一位张先生号码可能是 1024 或 1025 。 请大家谈谈如何将此语句优化。 大家优化后结果:
五、 update  、 delete 和  insert  语句的技巧 一次不只做一行,多行尽量做一次。 5.1 Update 的技巧: 使用 case 语句分修改分类条件 Update userinfo set  说明 =  ( case  when age > 20 and age <30  then  ‘ 年轻’ when age > 30 and age <40  then ‘ 健壮’ ) , … .. Where sex  = ‘ 男’ 以此类推一条语句可以更新好多的条件和字段。 5.2 insert  语句(不说也知道) Insert into table1 (  id  , username ) select userid , ‘ 张三’  from userinfo 5.3 delete 和  truncate 间的选择。 Delete 有事物可回滚, truncate 不可回滚。
六、关于关联的探讨 查询表顺序的影响 在 FROM 后面的表中的列表顺序会对 SQL 执行性能影响,在没有索引及 ORACLE 没有对表进行统计分析的情况下 ORACLE 会按表出现的顺序进行链接,由此因为表的顺序不对会产生十分耗服务器资源的数据交叉。(注:如果对表进行了统计分析, ORACLE 会自动先进小表的链接,再进行大表的链接) From  表一 ,表二 ,表三 From 表一  Inner join  表二  Inner join  表三 以上的关联请将数据量最小的表放在后面, sql 是 从右往左 运行的。 一些讨论: 客户 、订单、产品的关联。
7. 一些细节的东西 7.1Java 调用 sql 的提交尽量使用批量提交。 7.2 存储过程会快很多。 7.3 常用的复杂查询要写成 view 。 7.4 尽量使用内部函数
7.5 一些例句: 1. 减少对表的查询 SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604) 2. 用 EXISTS 替代 IN 、用 NOT EXISTS 替代 NOT IN : (高效) SELECT * FROM EMP ( 基础表 )WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB') ( 低效 )SELECT * FROM EMP ( 基础表 ) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB') 3. 用 EXISTS 替换 DISTINCT : ( 低效 ):SELECT  DISTINCT  DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO ( 高效 ):SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); 4. 用 >= 替代 > : 高效 :SELECT * FROM EMP WHERE DEPTNO >=4 低效 :SELECT * FROM EMP WHERE DEPTNO >3 5. 用 UNION 替换 OR ( 适用于索引列 ) : 高效 : SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION  WHERE LOC_ID = 10  UNION SELECT LOC_ID , LOC_DESC , REGION FROM  LOCATION WHERE REGION = “MELBOURNE” 低效 :SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 OR  REGION = “MELBOURNE” 其他例子请看预习文档
谢谢大家 Sql 优化一言难尽

More Related Content

PDF
Row Set初步学习V1.1
PPT
第9章 t sql程序设计
PDF
由一个简单的程序谈起――之二
PPT
Amos Learning
PDF
1.oracle 11g 用户管理新功能
PPT
Refactoring 重构
PDF
NeteaseBlog Objective-C Style Guide
Row Set初步学习V1.1
第9章 t sql程序设计
由一个简单的程序谈起――之二
Amos Learning
1.oracle 11g 用户管理新功能
Refactoring 重构
NeteaseBlog Objective-C Style Guide

What's hot (12)

PPT
第8章 数据完整性
DOC
希望科技研发部变量命名及编码规范
PDF
Csdn Emag(Oracle)第二期
PPT
Essential oracle security internal for dba
PPT
数据库原理第三章
PDF
Spring 2.x 中文
PDF
JavaScript 技術手冊第 5 章
PPT
Refactoring
PPT
Hibernate查询
DOC
Java 6中的线程优化真的有效么?
DOC
Spring入门纲要
PPT
Structs2簡介
第8章 数据完整性
希望科技研发部变量命名及编码规范
Csdn Emag(Oracle)第二期
Essential oracle security internal for dba
数据库原理第三章
Spring 2.x 中文
JavaScript 技術手冊第 5 章
Refactoring
Hibernate查询
Java 6中的线程优化真的有效么?
Spring入门纲要
Structs2簡介
Ad

Viewers also liked (8)

PPT
Visrhet Feb 19th 2014
DOCX
Trend Alert Foreign Language Media Gaining Ground
PPT
Visrhet, Feb 26th 2014
PPT
Feb 24th Monday Night VisRhet
PPT
VisRhet: Some Logos You Folks Made
PPT
Visual Rhetoric, Monday March 10, 2014
PPT
Social Media Stuff
PPT
Visual Rhetoric: M/W edition, March 3rd
Visrhet Feb 19th 2014
Trend Alert Foreign Language Media Gaining Ground
Visrhet, Feb 26th 2014
Feb 24th Monday Night VisRhet
VisRhet: Some Logos You Folks Made
Visual Rhetoric, Monday March 10, 2014
Social Media Stuff
Visual Rhetoric: M/W edition, March 3rd
Ad

Similar to Sql语句的优化 (20)

PPT
PHP Coding Standard and 50+ Programming Skills
PDF
MySQL数据库生产环境维护
PPT
Sql Server 高级技巧系列之三整体优化
PPTX
20130626联动优势数据访问层DAL架构和实践5(刘胜)数据分片和分页
PPT
lwdba – 開放原始碼的輕量級資料庫存取程式庫
DOC
Mdx解决方案(第二版)笔记
DOC
Free Marker中文文档
PDF
A.oracle 数据字典与脚本初步
PPT
组件交互模式的非主流研究
PDF
Jira 3.12.3不完全手册
PPT
Mybatis学习培训
PPT
山頂洞人日記 - 回歸到最純樸的開發
PPT
Oracle公司内部数据库培训资料
PDF
资身Dba经验谈
DOC
用Jquery实现拖拽层
PPTX
How to manipulate data in databases using Django Model API
PPT
Mongo db技术分享
PPT
数据库性能诊断的七种武器
DOC
上海立派信息技术有限公司
PHP Coding Standard and 50+ Programming Skills
MySQL数据库生产环境维护
Sql Server 高级技巧系列之三整体优化
20130626联动优势数据访问层DAL架构和实践5(刘胜)数据分片和分页
lwdba – 開放原始碼的輕量級資料庫存取程式庫
Mdx解决方案(第二版)笔记
Free Marker中文文档
A.oracle 数据字典与脚本初步
组件交互模式的非主流研究
Jira 3.12.3不完全手册
Mybatis学习培训
山頂洞人日記 - 回歸到最純樸的開發
Oracle公司内部数据库培训资料
资身Dba经验谈
用Jquery实现拖拽层
How to manipulate data in databases using Django Model API
Mongo db技术分享
数据库性能诊断的七种武器
上海立派信息技术有限公司

Sql语句的优化

  • 1. Sql 语句的优化 1 关于 sql 的语句分类 2sql 语句的执行顺序 3 说说 where 语句 4 关于子查询的巧用 5update 、 delete 和 insert 语句的技巧 6 关于关联的探讨 7 一些细节的东西
  • 2. 一、关于 sql 的语句分类 1.DDL 语句 用于建立各种数据库对象。(库、表、主键、外键、约束、索引。。。等) 2.DML 语句 insert 、 delete 、 update 3DCL 语句 各种权限控制语句
  • 3. 二、 sql 语句的执行顺序 执行顺序从右往左执行。 1. 插入语句 Insert into table ( column1 , column12 ,。。。) values ( value1,value2,… )的执行也是如此。 2.Select 语句 select 字段列表 from table where 条件 group by 字段列表 having 条件 order by 字段 ( desc|asc ) 执行顺序: where  group by ->having->order by ->select 列投影。 其中 where 的条件和 having 的条件是从右往左执行。 3.Update table set 字段设置 where 条件 执行顺寻: where ->set->update Where 条件从右往左执行。 4delete from table where 条件 执行顺序: where- 》 delete Where 条件从右往左执行。 总结:执行中的性能消耗主要在 where 语句的查询。
  • 4. 三、说说 where 语句 3.1 执行顺序。(从右往左 ,尽量在右边条件过滤掉大部分行) 根据业务逻辑调整条件,可以提高效率。 如 where sex =' 男 ' and age >20 慢 where age >20 and sex =' 男 ' 快 (因为按性别分可以一次过滤掉一半的行) 3.2 like 尽量少用。 like 语句进行模糊查询较慢。 3.3 between and 不如 > < 快 where between 20 and 40; 慢 where age >20 and age <40; 快 3.4 in 和 exists delete from userinfo where userid in ( select userid from user_status ); 慢 delete from userinfo A where exists ( select B.userid from user_status B where A.userid = B.userid ); 快 ( 由于是 delete 语句难以 inner join)
  • 5. 四、关于子查询的巧用 4.1 in 语句和子查询性能的万恶之源 通信证的一个 sql 优化的例子: 我在原有的项目中找到如下代码:(将性能瓶颈进行标红) select U.USERID userid, U.MOBILE mobile, U.USERNAME username, U.USERTYPE userType, US.LOGIN_TIMES, US.LASTLOGIN_DT, US.FREE_DL free_dl, UP.nickname nickname, (case when us.modelid is null then 0 else us.modelid end) mobid , (select ml.MODEL_NAME from model_list ml where ml.modelid = US.MODELID) mobModel from USERINFO U, USER_STATUS US, USER_PROFILE UP where U.USERID = US.USERID and U.USERID = UP.USERID AND (U.STATUS = 1 or U.STATUS = 2) and (U.USERNAME =’zhanghe’)
  • 6. 原则一尽量使用系统函数 (case when us.modelid is null then 0 else us.modelid end) mobid 可以用标准函数替代 Nvl(us.modelid , 0 ) 原则二避免列映射里面用子查询。 (select ml.MODEL_NAME from model_list ml where ml.modelid = US.MODELID) mobModel 这部分可以放到关联中 原则三查询条件不要总是马后炮 from USERINFO U, USER_STATUS US, USER_PROFILE UP where U.USERID = US.USERID and U.USERID = UP.USERID AND (U.STATUS = 1 or U.STATUS = 2) and (U.USERNAME =’zhanghe’) 这部分可以将特定表的查询提前。
  • 7. 最后我的优化语句为: ( 红色部分位修改 ) select U.USERID userid, U.MOBILE mobile, U.USERNAME username, U.USERTYPE userType, US.LOGIN_TIMES, US.LASTLOGIN_DT, US.FREE_DL free_dl, UP.nickname nickname, nvl(us.modelid,0) mobid , ml.MODEL_NAME mobModel from ( select * USERINFO U where (U.STATUS = 1 or U.STATUS = 2 )and (U.USERNAME =’zhanghe’) inner join USER_STATUS US on U.USERID = US.USERID inner join USER_PROFILE UP on U.USERID = UP.USERID left join model_list ml on ml.modelid = US.MODELID
  • 8. 4.2 几乎所有的子查询都能变为表连接( 我已经把表优化到最烂。呵呵! ) 请看 Select userid , username , ( select logintime from user_status where userid = u.userid ) logintime from userinfo u where userid in ( select userid from user_status where userid = u.userid ) where ( userid = 1024 or userid = 1025 ) and sex = ‘ 男’ and username like ‘’ 张 %; 此语句是有一位张先生号码可能是 1024 或 1025 。 请大家谈谈如何将此语句优化。 大家优化后结果:
  • 9. 五、 update 、 delete 和 insert 语句的技巧 一次不只做一行,多行尽量做一次。 5.1 Update 的技巧: 使用 case 语句分修改分类条件 Update userinfo set 说明 = ( case when age > 20 and age <30 then ‘ 年轻’ when age > 30 and age <40 then ‘ 健壮’ ) , … .. Where sex = ‘ 男’ 以此类推一条语句可以更新好多的条件和字段。 5.2 insert 语句(不说也知道) Insert into table1 ( id , username ) select userid , ‘ 张三’ from userinfo 5.3 delete 和 truncate 间的选择。 Delete 有事物可回滚, truncate 不可回滚。
  • 10. 六、关于关联的探讨 查询表顺序的影响 在 FROM 后面的表中的列表顺序会对 SQL 执行性能影响,在没有索引及 ORACLE 没有对表进行统计分析的情况下 ORACLE 会按表出现的顺序进行链接,由此因为表的顺序不对会产生十分耗服务器资源的数据交叉。(注:如果对表进行了统计分析, ORACLE 会自动先进小表的链接,再进行大表的链接) From 表一 ,表二 ,表三 From 表一 Inner join 表二 Inner join 表三 以上的关联请将数据量最小的表放在后面, sql 是 从右往左 运行的。 一些讨论: 客户 、订单、产品的关联。
  • 11. 7. 一些细节的东西 7.1Java 调用 sql 的提交尽量使用批量提交。 7.2 存储过程会快很多。 7.3 常用的复杂查询要写成 view 。 7.4 尽量使用内部函数
  • 12. 7.5 一些例句: 1. 减少对表的查询 SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604) 2. 用 EXISTS 替代 IN 、用 NOT EXISTS 替代 NOT IN : (高效) SELECT * FROM EMP ( 基础表 )WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB') ( 低效 )SELECT * FROM EMP ( 基础表 ) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB') 3. 用 EXISTS 替换 DISTINCT : ( 低效 ):SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO ( 高效 ):SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); 4. 用 >= 替代 > : 高效 :SELECT * FROM EMP WHERE DEPTNO >=4 低效 :SELECT * FROM EMP WHERE DEPTNO >3 5. 用 UNION 替换 OR ( 适用于索引列 ) : 高效 : SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 UNION SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE REGION = “MELBOURNE” 低效 :SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 OR REGION = “MELBOURNE” 其他例子请看预习文档