SQL语句优化

1,count

SELECT COUNT (*)
SELECT COUNT(1)
SELECT COUNT(字段名)
无主键时,count(1)快于count(*),如果字段中有Null则COUNT(字段名)不计数。

2,优化器

优化方式:RBO(基于规则的优化),CBO(基于代价的优化,Ora10g开始的默认设置。依赖于统计信息,需要及时更新统计信息)。
优化器的优化模式:Rule,Choose,First rows, All rows。
从Ora10g开始,All rows是默认设置。是Cost的方式。在CBO时ORACLE会自动来选择最优的执行计划。

各种模式如下:

* Rule: 走基于规则的方式。
* Choose: 10g前是默认方式。当表或索引有统计信息,走CBO方式;当表或索引无统计信息,表又不是特别的小,而且相应列有索引时,就走索引,即RBO方式。
* First rows: 和Choose类似,不同的是当表有统计信息时,他将以最快的方式返回查询的最先的几行,从总体上减少响应时间。
* All rows: 10g开始,为默认值。就是Cost的方式。当表有统计信息时,将以最快的方式返回表的所有行,从总体上提高查询吞吐量。没有统计信息则走RBO方式。

在CBO的模式下,我们需要做的就是:
1)做好数据库信息的相关统计
2)合理建设我们的索引
3)优化我们的SQL

3,查询代价

CBO通过代价引擎估计每个执行计划所需的代价,该代价将每个执行计划所耗费的资源进行量化,CBO根据这个代价选择最优的执行计划。

一个查询所消耗的资源分三部分:I/O代价,CPU代价,Newwork代价。
I/O代价,是把数据从磁盘读入内存所需的代价。这个代价是最主要的,所以在优化时的一个基本原则就是降低I/O总次数。
CPU代价,是处理内存中的数据所需的代价。如sort,join。
Newwork代价,对远程节点来说,这个花费也很大。

CBO(基于代价的优化器),需要表和索引等的统计数据,需要定期对表和索引进行分析。

4,RBO模式

select * from tbl where idx_item = xx;
如果idx_item列上有索引,那么会通过索引访问tbl。一般来说这是比较高效的,但特殊情况下索引反而低效。

索引效率低,FTS(Full Table Scan)更高效的情况。
1)tbl较小时,FTS效率高

      tbl较小时,数据只在几个数据块中,这个时候FTS更高效。因为数据全在内存中,FTS最快。
      而使用索引,则先从索引中找rowid,然后用rowid从表中读数据。这不但增加磁盘I/O,效率也比FTS低。

2)读取tbl比例大时,FTS效率高

     tbl较大时,当符合条件的数据有表的50%,如果共有4000万行,放在50万个数据快中每个数据块8K,那么表有4G。绝大部分需要放在硬盘上。

     如果一次能从硬盘读取200个数据块,那么FTS则 50万 / 200 = 2500次I/O;
     索引有可能都已经cache到内存中,4000万 * 50% = 2000万数据。假设命中率99.9%,则要2000万 * (1-99.9%)= 20000次I/O。
     所以索引比FTS代价高。

5,数据块

当创建一个Oracle数据库时,选择一个基于操作系统块的整数倍大小作为Oracle数据库块的大小。Oracle数据库读写操作则是以Oracle块为最小单位。

数据库块也称逻辑块或Oracle块,它对应磁盘上一个或多个物理块,

它的大小由初始化参数  DB_BLOCK_SIZE  决定,可以定义数据块为2K、4K、8K、16K、32K甚至更大,默认8K

若一旦设置了Oracle数据块的大小,则在整个数据库生命期间不能被更改。使用一个合适的Oracle块大小对于数据库的调优是非常重要的。

< 查看 >

SQL> show parameter db_block_size
NAME                    TYPE         VALUE
------------------------------------ -----------------
db_block_size        integer       8192

6,索引

索引是不需要修改SQL最直接带来性能提升的利器,何时该建索引,怎么建?怎么样让你的索引更合理?

参见,建立索引常用的规则(https://www.cnblogs.com/makesunny/p/14500225.html)

 7,

posted on 2021-01-31 21:38  至柔  阅读(82)  评论(0)    收藏  举报

导航