认识SQL优化、基数和选择性

版本:Oracle 11G R2

环境:SQLPlus

用户:scott

1.SQL优化,首先需要知道SQL的性能瓶颈在哪里

优化一个系统选择: (1)应用架构优化 (2)数据库db优化

应用架构优化运维年限太长,优化难度太大,所以我们只能从数据库db优化

2.数据库的优化

(1) 参数、配置、硬件优化等等占20%

(2) SQL优化占80%

3.学习SQL优化是学习思路,不是学会看执行计划。

主要是SQL优化的核心思想,以及SQL优化的具体操作步骤和方法,重点并不是讲理论。但是这个也有一些核心的基础理论,少了这些基础理论,那后面的学习也就没意义了,因为没基础可能听不懂。前期会有一些基础理论,后期会大量讲解SQL优化的具体步骤,优化方法,以及案例分析。

4.基数和选择性

基数(Cardinality) 列唯一键(Distinct_keys)的数量,比如性别,该列只有男女之分,所以这一列基数是2。主键列的基数等于行数。

选择性(Selectivity) 列唯一键(Distinct_Keys)与行数(Num_Rows)的比值。

举例4.1:

有一个表test有1000W行,id是主键列。

主键列的基数 :1000W;

非主键列的基数:select count(distinct 非主键列名) from test;

举例4.2:

有一个表test有1000W行,id是主键列,gender是性别列,男女各占一半

基数很多:select * from test where id = '10' 返回1条,是不是应该走索引?

基数很少:select * from test where gender = 'M'返回500W条,是不是应该走全表扫描?

5.基数的多少跟走不走索引有没有关系?

一般情况下:

(1)基数越多,返回数据就越少

(2)基数越多,就越适合建立索引

(3)基数越少,就不适合建立索引

举例5.1:

有一个表test有1000W行,gender是性别列,男人有1W,女人有999W。

select * from test where gender = ‘M’ 走索引or全表扫描?

select * from test where gender = ‘F’ 走全表扫描

6.查询真实的基数和选择性

我们在进行SQL调优的时候,可以用下面SQL去查看列真实的基数和选择性

select count(distinct column_name),

count(*) total_rows,

count(distinct column_name) / count(*) * 100 selectivity

from table_name;

直方图

1、基于规则的优化方式(Rule-Based Optimization,简称为RBO)

优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则,对数据是不敏感的。它只借助少量的信息来决定一个sql语句的执行计划,包括:

1) sql语句本身

2) sql中涉及到的table、view、index等的基本信息

例如:我们常见的,当一个where子句中的一列有索引时去走索引。但是需要注意,走索引不一定就是优的,比如一个表只有两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时全表扫描(table_access_full)的效率更优。

在得到目标SQL的执行计划时,RBO所用的判断原则为一组内置的规则,这些规则是硬编码在Oracle数据库的代码中,RBO根据这些规则从目标SQL可能的执行路径中选择一条作为最终的执行计划;

具体是这样的:Oracle 会在代码里事先给各种类型的执行路径定一个等级,一共有15个等级,优先级从等级1到等级15(等级1值最低,等级最高)。Oracle会认为等级值低的执行效率比等级值高的效率高,也就是说,等级越高效率越高。可是在决定目标SQL的执行计划时可能不止一条执行计划,那么RBO就会从SQL诸多可能的执行计划中选择一条等级值最低的执行路径作为最终的执行计划。

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();