搜索
首页数据库mysql教程Oracle优化SQL语句

Oracle优化SQL语句

Jun 07, 2016 pm 03:50 PM
oraclesql了解优化我们相关索引语句

我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。我们一般是通过索引查询数据比全表扫描要快。当 Oracle找出执行查询和Update语句的最好路径时,Oracle优化将使用索引。同样在联结多个表时使用

我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。我们一般是通过索引查询数据比全表扫描要快。当 Oracle找出执行查询和Update语句的最好路径时, Oracle优化将使用索引。同样在联结多个表时使用索引也能够提高效率。

另一个使用索引的好处是,他提供了主键(primary key)的唯一性验证。那些LONG或LONG RAW数据类型, 您能够索引几乎任何的列。通常, 在大型表中使用索引特别有效. 当然,您也会发现, 在扫描小表时,使用索引同样能提高效率。虽然使用索引能得到查询效率的提高,但是我们也必须注意到他的代价。

索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。这意味着每条记录的INSERT,DELETE , UPDATE将为此多付出4、 5次的磁盘I/O 。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。定期的重构索引是有必要的:

ALTER INDEX REBUILD

1.用EXISTS替换DISTINCT:

当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT。一般能够考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立即返回结果。例子:

(低效): 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);

2.SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。

3.在Java代码中尽量少用连接符“+”连接字符串。

4.避免在索引列上使用NOT通常,我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响。当Oracle“碰到”NOT,他就会停止使用索引转而执行全表扫描。

5.避免在索引列上使用计算。WHERE子句中,假如索引列是函数的一部分。Oracle优化器将不使用索引而使用全表扫描。

举例:

低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SELECT … FROM DEPT WHERE SAL > 25000/12;

6.用>=替代>:

高效:SELECT * FROM EMP WHERE DEPTNO >=4 低效: SELECT * FROM EMP WHERE DEPTNO >3

两者的区别在于,前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录。

7.用UNION替换OR (适用于索引列):

通常情况下,用UNION替换WHERE子句中的OR将会起到较好的效果。对索引列使用OR将造成全表扫描。注意,以上规则只针对多个索引列有效。假如有column没有被索引,查询效率可能会因为您没有选择OR而降低。在下面的例子中,LOC_ID 和REGION上都建有索引。

高效: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”

8.用IN来替换OR:

这是一条简单易记的规则,但是实际的执行效果还须检验,在Oracle8i下,两者的执行路径似乎是相同的:

低效:

SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30

高效:

SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);

9.避免在索引列上使用IS NULL和IS NOT NULL:

避免在索引中使用任何能够为空的列,Oracle将无法使用该索引。对于单列索引,假如列包含空值,索引中将不存在此记录。对于复合索引,假如每个列都为空,索引中同样不存在此记录。假如至少有一个列不为空,则记录存在于索引中。举例:假如唯一性索引建立在表的A列和B列上,并且表中存在一条记录的 A,B值为(123,null), Oracle将不接受下一条具备相同A,B值(123,null)的记录(插入)。

然而假如任何的索引列都为空,Oracle将认为整个键值为空而空不等于空。因此您能够插入1000 条具备相同键值的记录,当然他们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使Oracle停用该索引。

低效: (索引失效)

<ol><li><span>SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL; </span></li></ol>

高效:(索引有效)

<ol><li><span><span>SELECT … FROM DEPARTMENT WHERE DEPT_CODE </span><span>></span><span>=0; </span></span></li></ol>

10.总是使用索引的第一个列:

假如索引是建立在多个列上,只有在他的第一个列(leading column)被where子句引用时,Oracle优化器才会选择使用该索引。这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引。

11.用UNION-ALL 替换UNION ( 假如有可能的话):

当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,然后在输出最终结果前进行排序。假如用 UNION ALL替代UNION,这样排序就不是必要了。效率就会因此得到提高。需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录。因此各位还是要从业务需求分析使用UNION ALL的可行性。 UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存。对于这块内存的Oracle优化也是相当重要的。下面的SQL能够用来查询排序的消耗量:

低效: SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' UNION SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' 高效: SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95' UNION ALL SELECT ACCT_NUM, BALANCE_AMT FROM DEBIT_TRANSACTIONS WHERE TRAN_DATE = '31-DEC-95'


如果你是Oracle多表查询优化方面的新手,对Oracle多表查询优化的相关实际应用不是很了解的话,以下的文章会给你提供更全面的知识。以下就是文章的详细内容的介绍,望你会有所了解。

Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

例如:

(低效,执行时间156.3秒)

<ol>
<li><span>SELECT …  </span></li>
<li><span>FROM EMP E  </span></li>
<li>
<span>WHERE SAL </span><span>></span><span>; 50000  </span>
</li>
<li>
<span>AND </span><span>JOB</span><span> = ‘MANAGER’  </span>
</li>
<li>
<span>AND 25 </span><span><span> (SELECT COUNT(*) FROM EMP  </span></span>
</li>
<li>
<span>WHERE </span><span>MGR</span><span>=</span><span>E</span><span>.EMPNO);  </span>
</li>
</ol>

(高效,执行时间10.6秒)

<ol>
<li><span>SELECT …  </span></li>
<li><span>FROM EMP E  </span></li>
<li>
<span>WHERE 25 </span><span><span> (SELECT COUNT(*) FROM EMP  </span></span>
</li>
<li>
<span>WHERE </span><span>MGR</span><span>=</span><span>E</span><span>.EMPNO)  </span>
</li>
<li>
<span>AND SAL </span><span>></span><span>; 50000  </span>
</li>
<li>
<span>AND </span><span>JOB</span><span> = ‘MANAGER’;  </span>
</li>
</ol>

重点关注3:SELECT子句中避免使用 ‘ * ‘ .重点关注

当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,Oracle在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过Oracle多表查询数据字典完成的, 这意味着将耗费更多的时间.

7. 减少访问数据库的次数

当执行每条SQL语句时, Oracle在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少Oracle的工作量.

例如,

以下有三种方法可以检索出雇员号等于0342或0291的职员.

方法1 (最低效)

<ol>
<li><span>SELECT EMP_NAME , SALARY , GRADE  </span></li>
<li><span>FROM EMP  </span></li>
<li>
<span>WHERE </span><span>EMP_NO</span><span> = </span><span>342</span><span>;  </span>
</li>
<li><span>SELECT EMP_NAME , SALARY , GRADE  </span></li>
<li><span>FROM EMP  </span></li>
<li>
<span>WHERE </span><span>EMP_NO</span><span> = </span><span>291</span><span>;  </span>
</li>
</ol>

方法2 (次低效)

<ol>
<li><span>DECLARE  </span></li>
<li><span>CURSOR C1 (E_NO NUMBER) IS  </span></li>
<li><span>SELECT EMP_NAME,SALARY,GRADE  </span></li>
<li><span>FROM EMP  </span></li>
<li>
<span>WHERE </span><span>EMP_NO</span><span> = </span><span>E_NO</span><span>;  </span>
</li>
<li><span>BEGIN  </span></li>
<li><span>OPEN C1(342);  </span></li>
<li><span>FETCH C1 INTO …,..,.. ;  </span></li>
<li><span>OPEN C1(291);  </span></li>
<li><span>FETCH C1 INTO …,..,.. ;  </span></li>
<li><span>CLOSE C1;  </span></li>
<li><span>END;  </span></li>
</ol>

以上的相关内容就是对Oracle多表查询优化的介绍,望你能有所收获。


声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
MySQL中有哪些不同的存储引擎?MySQL中有哪些不同的存储引擎?Apr 26, 2025 am 12:27 AM

mysqloffersvariousStorageengines,每个suitedfordferentusecases:1)InnodBisidealForapplicationsNeedingingAcidComplianCeanDhighConcurncurnency,supportingtransactionsancions and foreignkeys.2)myisamisbestforread-Heavy-Heavywyworks,lackingtransactionsactionsacupport.3)记忆

MySQL中有哪些常见的安全漏洞?MySQL中有哪些常见的安全漏洞?Apr 26, 2025 am 12:27 AM

MySQL中常见的安全漏洞包括SQL注入、弱密码、权限配置不当和未更新的软件。1.SQL注入可以通过使用预处理语句防止。2.弱密码可以通过强制使用强密码策略避免。3.权限配置不当可以通过定期审查和调整用户权限解决。4.未更新的软件可以通过定期检查和更新MySQL版本来修补。

您如何确定MySQL中的慢速查询?您如何确定MySQL中的慢速查询?Apr 26, 2025 am 12:15 AM

在MySQL中识别慢查询可以通过启用慢查询日志并设置阈值来实现。1.启用慢查询日志并设置阈值。2.查看和分析慢查询日志文件,使用工具如mysqldumpslow或pt-query-digest进行深入分析。3.优化慢查询可以通过索引优化、查询重写和避免使用SELECT*来实现。

如何监视MySQL Server的健康和性能?如何监视MySQL Server的健康和性能?Apr 26, 2025 am 12:15 AM

要监控MySQL服务器的健康和性能,应关注系统健康、性能指标和查询执行。1)监控系统健康:使用top、htop或SHOWGLOBALSTATUS命令查看CPU、内存、磁盘I/O和网络活动。2)追踪性能指标:监控查询每秒数、平均查询时间和缓存命中率等关键指标。3)确保查询执行优化:启用慢查询日志,记录并优化执行时间超过设定阈值的查询。

比较和对比Mysql和Mariadb。比较和对比Mysql和Mariadb。Apr 26, 2025 am 12:08 AM

MySQL和MariaDB的主要区别在于性能、功能和许可证:1.MySQL由Oracle开发,MariaDB是其分支。2.MariaDB在高负载环境中性能可能更好。3.MariaDB提供了更多的存储引擎和功能。4.MySQL采用双重许可证,MariaDB完全开源。选择时应考虑现有基础设施、性能需求、功能需求和许可证成本。

MySQL的许可与其他数据库系统相比如何?MySQL的许可与其他数据库系统相比如何?Apr 25, 2025 am 12:26 AM

MySQL使用的是GPL许可证。1)GPL许可证允许自由使用、修改和分发MySQL,但修改后的分发需遵循GPL。2)商业许可证可避免公开修改,适合需要保密的商业应用。

您什么时候选择InnoDB而不是Myisam,反之亦然?您什么时候选择InnoDB而不是Myisam,反之亦然?Apr 25, 2025 am 12:22 AM

选择InnoDB而不是MyISAM的情况包括:1)需要事务支持,2)高并发环境,3)需要高数据一致性;反之,选择MyISAM的情况包括:1)主要是读操作,2)不需要事务支持。InnoDB适合需要高数据一致性和事务处理的应用,如电商平台,而MyISAM适合读密集型且无需事务的应用,如博客系统。

在MySQL中解释外键的目的。在MySQL中解释外键的目的。Apr 25, 2025 am 12:17 AM

在MySQL中,外键的作用是建立表与表之间的关系,确保数据的一致性和完整性。外键通过引用完整性检查和级联操作维护数据的有效性,使用时需注意性能优化和避免常见错误。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器