【sql调优之执行计划】estimator i

Oracleestimator(评估器)产生3种不同类型的评估量:

Selectivity选择性

Cardinality集势

Cost开销

这些评估量互相之间是关联的,estimator的目的是评估plan的整体cost,如果统计信息是可用的,estimator将使用统计信息来计算评估量。

Selectivity

选择性是指从行集中返回的行的比例,行集可以是基本表,视图,或者是由join或者group by等操作产生的结果集。Selectivity取决于查询谓词(predicate)或者查询谓词的组合。谓词的选择性表明了限定谓词后返回多少行。选择性的取值范围是01,选择性为0意味着没有从行集中选择行,为1则意味着选择了所有行。

当统计信息可用的时候estimator使用它来评估选择性,比如一个相等谓词(equality predicate)ename=’Smith’,选择性就为1/distinct(ename),如果ename上有可用的直方图,那么评估器使用直方图来计算选择性,而不是用distinct value。直方图记录了列上不同值的分布,所以将较好的评价选择性,这个很好理解。

Cardinality

集势表示行集的行数,同样这里的行集可以是基本表,视图,或者joingroup by等操作的结果集。

Base cardinality是指基本表的行数,可以通过analyze table来获得,如果表统计信息不可用,estimator将使用tableextents数来评估base cardinality

 

Effective cardinality是指从表中选择的行,如果基础表上没有谓词,那么它就等于表的Base cardinality

例子:

SQL> explain plan for

  2  select * from dual;

 

已解释。

SQL> select * from dual;

 

D

-

X

 

 

执行计划

----------------------------------------------------------

Plan hash value: 272002086

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     1 |     2 |     2   (0)| 00:00:01 |

|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |

--------------------------------------------------------------------------

SQL> select a.operation,a.cardinality,a.cost from plan_table a;

 

OPERATION                      CARDINALITY       COST

------------------------------ ----------- ----------

SELECT STATEMENT                         1          2

TABLE ACCESS                             1          2

再看一个例子:

SQL> explain plan for

  2  select a.empno,a.ename from scott.emp a where a.deptno < 20 ;

 

已解释。

 

SQL> select a.empno,a.ename from scott.emp a where a.deptno < 20 ;

 

     EMPNO ENAME

---------- ----------

      7782 CLARK

      7839 KING

      7934 MILLER

 

 

执行计划

----------------------------------------------------------

Plan hash value: 3956160932

 

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     4 |    52 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| EMP  |     4 |    52 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("A"."DEPTNO"<20)

..

SQL> select a.operation,a.cardinality,a.cost from plan_table a;

 

OPERATION                      CARDINALITY       COST

------------------------------ ----------- ----------

SELECT STATEMENT                         4          3

TABLE ACCESS                             4          3

可以看到这里的cardinality并不是期待的3,如果返回的行为0(比如使用<10rownum<1等条件),cardinality也是1,就这个例子而言,使用<的条件始终比行数要多1,而=,>=,<=则与返回的行数一致。

事实上这种情况(全表扫描)的cardinality可以这样计算:num_rows*表的选择性=15*(1/20+1/3)=5.75

其中对于非索引字段,,>=,<=,<>,not in等的选择性=1/20+1/字段唯一值数)

=的选择性=1/100+1/字段唯一值数)

对于索引字段的选择性,=的选择性是1/字段唯一值数

而其他的则是(1/字段唯一值数+1/记录数)

不一一累述。

 

Join cardinalityjoin后产生的行数,是两个行集的cardinality的乘积,然后乘以连接谓词的选择性的结果。看个例子

笛卡尔乘积,很显然笛卡尔乘积没有连接条件,选择性为1,选择所有join后的结果

则:

SQL> explain plan for

  2  select a.empno,a.ename,a.* from scott.emp a,scott.dept b ;

 

已解释。

 

SQL> select a.operation,a.cardinality,a.cost from plan_table a;

 

OPERATION                      CARDINALITY       COST

------------------------------ ----------- ----------

SELECT STATEMENT                        60          7

MERGE JOIN                              60          7

INDEX                                    4          1

BUFFER                                  15          6

TABLE ACCESS                            15          2

Cardinality为两者的cardinality的乘积4*15=60

修改一下上述查询,增加条件:

SQL> explain plan for

  2  select a.empno,a.ename,b.dname from scott.emp a,scott.dept b

  3  where  a.deptno = b.deptno

  4  and a.sal < 2000

  5  ;

 

已解释。

SQL> select a.operation,a.cardinality,a.cost from plan_table a;

 

OPERATION                      CARDINALITY       COST

------------------------------ ----------- ----------

SELECT STATEMENT                         6          4

NESTED LOOPS                             6          4

TABLE ACCESS                             6          3

TABLE ACCESS                             1          1

INDEX                                    1          0

增加了a.sal<2000以后,看看这时候的cardinality是如何计算的:

SQL> select count(*) from scott.emp a ;

 

  COUNT(*)

----------

        15

SQL> select count(*) from scott.dept a ;

 

  COUNT(*)

----------

         4

SQL> select count(*) from scott.emp a where a.sal < 2000 ;

 

  COUNT(*)

----------

         9

SQL> select count(*) from scott.dept a where a.deptno in

  2  (select a.deptno from scott.emp a where a.sal < 2000 )

  3  ;

 

  COUNT(*)

----------

         3

 

看看具体的执行计划:

SQL> select a.empno,a.ename,b.dname from scott.emp a,scott.dept b

  2  where  a.deptno = b.deptno

  3  and a.sal < 2000

  4  ;

 

执行计划

----------------------------------------------------------

Plan hash value: 351108634

 

--------------------------------------------------------------------------------

--------

| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Ti

me     |

--------------------------------------------------------------------------------

--------

|   0 | SELECT STATEMENT             |         |     6 |   156 |     4   (0)| 00

:00:01 |

|   1 |  NESTED LOOPS                |         |     6 |   156 |     4   (0)| 00

:00:01 |

|*  2 |   TABLE ACCESS FULL          | EMP     |     6 |    78 |     3   (0)| 00

:00:01 |

|   3 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    13 |     1   (0)| 00

:00:01 |

|*  4 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00

:00:01 |

--------------------------------------------------------------------------------

--------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - filter("A"."SAL"<2000)

   4 - access("A"."DEPTNO"="B"."DEPTNO")

上面这些数值按照之前描述的算法计算,两个行集的cardinality乘积乘以join谓词的选择性:

对于nested loops join,hash join ,sort merge join来说选择性可以有这样的计算公式:

Join Selectivity =
((num_rows(t1) - num_nulls(t1.c1)) / num_rows(t1)) *
((num_rows(t2) - num_nulls(t2.c2)) / num_rows(t2)) /
greater(num_distinct(t1.c1), num_distinct(t2.c2))

9*3*((15-0)/15*(4-0)/4/greatest(3,4))

cardinality= Join Selectivity *filtered cardinality(t1) * filtered cardinality(t2)

故而可以计算出cardinality

SQL> Select 9*3*((15-0)/15*(4-0)/4/greatest(3,4)) from dual;

 

9*3*((15-0)/15*(4-0)/4/GREATEST(3,4))

-------------------------------------

                                 6.75

 

Distinct cardinality

是行集中某一列的distinct

 

Group cardinality

是一个行集在应用了group by操作后产生的行数

9i文档中描述如下:

group cardinality lies between max ( dist. card. colx , dist. card. coly )

                               and min ( (dist. card. colx * dist. card. coly) ,

                               num rows in row set )

 

 

 

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16179598/viewspace-671532/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16179598/viewspace-671532/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XGBoost是一种用于机器学习的强大算法,它可以在分类和回归任务中获得很好的性能。但是,为了达到最佳性能,需要对其超参数进行调整。 以下是XGBoost中需要调整的一些重要超参数: 1. n_estimators:决定树的数量,也就是模型中的基本学习者数量。 2. max_depth:树的最大深度,过高的深度可能导致过度拟合。 3. learning_rate:控制每个基本学习器的权重更新步长。 4. subsample:每次训练模型时用于构建树的样本比例。 5. colsample_bytree:每次训练模型时用于构建树的特征比例。 6. gamma:控制当树分裂时,节点的最小损失减少量。 7. reg_alpha:L1正则化参数,用于控制模型的复杂度。 8. reg_lambda:L2正则化参数,用于控制模型的复杂度。 下面是一个简单的XGBoost参数调优示例: ```python import xgboost as xgb from sklearn.datasets import load_digits from sklearn.model_selection import GridSearchCV # 加载数据集 digits = load_digits() X, y = digits.data, digits.target # 定义参数范围 param_grid = {'n_estimators': [50, 100, 150], 'max_depth': [2, 3, 4], 'learning_rate': [0.01, 0.1, 0.5], 'subsample': [0.6, 0.8, 1.0], 'colsample_bytree': [0.6, 0.8, 1.0], 'gamma': [0, 0.1, 0.2], 'reg_alpha': [0, 0.1, 1], 'reg_lambda': [0, 0.1, 1]} # 定义分类器 xgb_model = xgb.XGBClassifier(objective='multi:softmax', num_class=10) # 定义网格搜索 grid_search = GridSearchCV(estimator=xgb_model, param_grid=param_grid, cv=5, n_jobs=-1) # 进行参数调优 grid_search.fit(X, y) # 输出最佳参数 print("Best parameters found: ", grid_search.best_params_) ``` 在上面的代码中,我们使用了网格搜索来寻找最佳超参数。我们定义了一个参数范围字典,包含了所有需要调整的超参数及其可能的值。然后,我们定义了一个XGBoost分类器,并将其作为估计器传递给网格搜索。最后,我们调用fit()方法来运行网格搜索,找到最佳参数组合。 总的来说,XGBoost是一种非常强大的机器学习算法,但是需要调整一些重要的超参数才能实现最佳性能。通过调整这些超参数,可以使XGBoost在分类和回归任务中获得更好的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值