如何写出高效的sql的一点想法
迷糊的问题:
1.什么样的sql,才算是高效的sql呢?
2.sql为什么不走索引?如何让sql走索引,即改变sql的执行计划
3.索引有哪几种?
4,什时候用索引,什么时候全表扫描
oracle优化器的表统计信息,评估出表的最佳连接顺序,表的连接方法,执行路径;
最后生成执行计划,oracle就按着这个计划来执行sql
1.什么样的sql是高效sql?
答:最本质答案就是执行时间最短,怎么才能最短了,就是用最少的资源把事办了,不做无用功;
即使sql的io最少,那怎么样才才能最少呢?就是尽量用索引,不要全表扫描;在多表关联的
时候,开发人选正确的表连接方法,执行路径等
2.sql为何不走索引
A.类型不匹配
B。条件列包含函数但没有创建相应的函数索引
C。复合索引中的前导列没有被做为查询条件
D。CBO的模式下,选择的行数比例较大,优化器选择全表扫描
E。CBO的模式下,表很久没有分析,优化器选择了全表扫描
3.索引种类及创建方法
A。B*索引
create index indexname on tablename(columnname);
B.反向索引
create index indexname on tablename(columnname) reverse;
C.降序索引
create index indexname on tablename(columnname desc);
D.位图索引
create bitmap index indexname on tablename(columnname);
E。函数索引
create index indexname on tablename(functionname(columnname));
4,什时候用索引,什么时候用全表扫描?
答:
要使用索引时,首先要弄清一些基本信息
表有多少行?查询返回多少行?表的哪些列上有索引?都是什么样的索引?
在有多个条件列时,应该选择什么样的索引?
A.当查询的记录数,在有序表中小于40%的时候,最好用索引;否则用全表扫描
B.当查询的记录数,在有无序表中小于7%的时候,最好用索引;否则用全表扫描
C.表的锁片较多时(这个表dml操作很频繁)
oracle常用hint的用法
写HINT目的
手工指定SQL语句的执行计划
hints是oracle提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。我们可以用hints来实现:
1) 使用的优化器的类型
2) 基于代价的优化器的优化目标,是all_rows还是first_rows。
3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用rowid。
4) 表之间的连接类型
5) 表之间的连接顺序
6) 语句的并行程度
2、HINT可以基于以下规则产生作用
表连接的顺序、表连接的方法、访问路径、并行度
3、HINT应用范围
dml语句
查询语句
4、语法
{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */
or
{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...
如果语(句)法不对,则ORACLE会自动忽略所写的HINT,不报错
1. /*+ALL_ROWS*/
表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.
例如:
SELECT /*+ALL_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
2. /*+FIRST_ROWS*/
表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.
例如:
SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
3. /*+CHOOSE*/
表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;
表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;
例如:
SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
4. /*+RULE*/
表明对语句块选择基于规则的优化方法.
例如:
SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
5. /*+FULL(TABLE)*/
表明对表选择全局扫描的方法.
例如:
SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';
6. /*+ROWID(TABLE)*/
提示明确表明对指定表根据ROWID进行访问.
例如:
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'
AND EMP_NO='SCOTT';
7. /*+CLUSTER(TABLE)*/
提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.
例如:
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
8. /*+INDEX(TABLE INDEX_NAME)*/
表明对表选择索引的扫描方法.
例如:
SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
9. /*+INDEX_ASC(TABLE INDEX_NAME)*/
表明对表选择索引升序的扫描方法.
例如:
SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';
10. /*+INDEX_COMBINE*/
为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.
例如:
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS
WHERE SAL<5000000 AND HIREDATE
11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
提示明确命令优化器使用索引作为访问路径.
例如:
SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
FROM BSEMPMS WHERE SAL<60000;
12. /*+INDEX_DESC(TABLE INDEX_NAME)*/
表明对表选择索引降序的扫描方法.
例如:
SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';
13. /*+INDEX_FFS(TABLE INDEX_NAME)*/
对指定的表执行快速全索引扫描,而不是全表扫描的办法.
例如:
SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';
14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
提示明确进行执行规划的选择,将几个单列索引的扫描合起来.
例如:
SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306';
15. /*+USE_CONCAT*/
对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.
例如:
SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';
16. /*+NO_EXPAND*/
对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.
例如:
SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';
17. /*+NOWRITE*/
禁止对查询块的查询重写操作.
18. /*+REWRITE*/
可以将视图作为参数.
19. /*+MERGE(TABLE)*/
能够对视图的各个查询进行相应的合并.
例如:
SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO
AND A.SAL>V.AVG_SAL;
20. /*+NO_MERGE(TABLE)*/
对于有可合并的视图不再合并.
例如:
SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;
21. /*+ORDERED*/
根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.
例如:
SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;
22. /*+USE_NL(TABLE)*/
将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.
例如:
SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
23. /*+USE_MERGE(TABLE)*/
将指定的表与其他行源通过合并排序连接方式连接起来.
例如:
SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
24. /*+USE_HASH(TABLE)*/
将指定的表与其他行源通过哈希连接方式连接起来.
例如:
SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
25. /*+DRIVING_SITE(TABLE)*/
强制与ORACLE所选择的位置不同的表进行查询执行.
例如:
SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;
26. /*+LEADING(TABLE)*/
将指定的表作为连接次序中的首表.
27. /*+CACHE(TABLE)*/
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
28. /*+NOCACHE(TABLE)*/
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
29. /*+APPEND*/
直接插入到表的最后,可以提高速度.
insert /*+append*/ into test1 select * from test4 ;
30. /*+NOAPPEND*/
通过在插入语句生存期内停止并行模式来启动常规插入.
insert /*+noappend*/ into test1 select * from test4 ;
31. NO_INDEX: 指定不使用哪些索引
/*+ NO_INDEX ( table [index [index]...] ) */
select /*+ no_index(emp ind_emp_sal ind_emp_deptno)*/ * from emp where deptno=200 and sal>300;
32. parallel
select /*+ parallel(emp,4)*/ * from emp where deptno=200 and sal>300;
另:每个SELECT/INSERT/UPDATE/DELETE命令后只能有一个/*+ */,但提示内容可以有多个,可以用逗号分开,空格也可以。如:
/*+ ordered index() use_nl() */
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wyzxg/archive/2009/05/15/4187763.aspx
分享到:
相关推荐
如何写出高效率的SQL语句--SQL优化技巧 SQL 优化技巧是提高数据库性能的关键所在。编写高效率的 SQL 语句需要对索引的机制有一定了解,以下是关于索引的知识点: 索引的优点和局限 索引可以提高查询的效率,但会...
在编写 SQL 语句时,应该使用格式一致的 SQL 语句,包括字母的大小写、标点符号、换行的位置等,以减少 SQL 分析编译开销。 14. 游标、动态 SQL 语句尽量用绑定变量方式调用 在编写 SQL 语句时,应该尽量使用绑定...
### 教你写出高效的SQL语句 在数据库管理和数据分析领域,编写高效、优化的SQL语句是提升系统性能的关键。本文将深入解析一系列实用的技巧和最佳实践,旨在帮助读者改进其SQL编程习惯,实现更快速的数据检索和处理...
【如何编写高效SQL语句】 在数据库管理中,编写高效的SQL语句对于系统性能的优化至关重要。本篇将深入探讨性能调整的综合观点、有效应用设计以及SQL语句处理的过程,帮助你提升数据库系统的整体效率。 首先,性能...
《高效SQL学习笔记》 SQL,全称Structured Query Language,即结构化查询语言,是用于管理关系数据库的标准语言。高效地掌握SQL对于任何IT从业者,尤其是数据分析师、数据库管理员和开发人员来说,都是至关重要的...
以下是从提供的文件内容中提炼出的关键知识点,旨在帮助开发者编写高效的SQL语句。 1. 使用索引 在编写SQL时,合理利用数据库索引是提高查询效率的重要手段。索引能够帮助数据库更快地定位到数据,减少对表的全表...
4. **性能分析**:内置的性能分析器可以帮助我们快速识别慢查询,提供优化建议,帮助我们写出更高效的SQL语句,从而提升数据库的运行效率。 5. **模板与片段**:预定义的SQL模板和自定义代码片段,让我们能够快速...
高效SQL语句测试使用没什么用不要浪费时间
SQL 基础 SQL 首页 SQL 简介 SQL 语法 SQL select SQL distinct SQL where SQL AND & OR SQL Order By SQL insert SQL update SQL delete SQL 高级 SQL Top SQL Like SQL 通配符 SQL In SQL Between ...
在Win10、Win8和Win7 64位系统上,SQLTracker表现稳定且高效,能够准确地反映出数据库操作的情况。 然而,对于32位的操作系统,由于可能存在的兼容性问题,推荐使用SQLMonitor作为替代工具。SQLMonitor同样具备强大...
在SQL(Structured Query Language)中,循环语句主要...然而,理解何时使用循环以及如何优化循环对于编写高效、可维护的SQL代码至关重要。在实际应用中,我们需要根据具体情况选择合适的循环结构,并考虑性能因素。
sql学习 with字句的高效.sql
SQLSearch插件工具是一款专为SQL Server Management Studio (SSMS) 设计的高效辅助工具,旨在简化和加速SQL代码的搜索过程。这款插件适用于多种版本的SQL Server,包括2021、2014、2016以及2017。它的主要功能在于...
SQL Server 导入超大 SQL 脚本文件 SQL Server 是一种关系型数据库管理系统,广泛应用于各种行业。然而,在实际应用中,我们经常会遇到导入超大 SQL 脚本文件的问题。本文将介绍如何使用 osql 工具来导入超大 SQL ...
如何编写高效的SQL代码,包括优化原则及经验之谈
在IT行业中,数据库管理系统是核心组成部分,SQL Server和Oracle分别是微软和甲骨文公司推出的两款广泛应用的关系型数据库系统。在企业级应用中,有时需要在不同的数据库系统间进行数据迁移或兼容性处理,这就涉及到...
python 通过adodbapi读写sqlserver image字段类型。
SQLPrompt for SQLServer2016 智能提示插件 SQL2016 提示 SQLPrompt最新版本 绿色版 SQL Prompt 是一款拥有SQL智能提示功能的SQL Server和VS插件。SQL Prompt能根据数据库的对象名称,语法和用户编写的代码片段自动...
强大的脚本编辑器支持自定义快捷键和代码折叠,让用户可以高效地编写和运行SQL脚本。 8. **导入导出工具** 支持多种格式的数据导入导出,如CSV、XML、Excel等,便于数据迁移和分析。 9. **安全与权限管理** ...