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,
浙公网安备 33010602011771号