当前位置: 首页 > news >正文

校园网站建设 方案论证公司电脑管理软件

校园网站建设 方案论证,公司电脑管理软件,usp理论案例100例,网站建设课程下载作者:胡呈清,爱可生公司旗下的DBA团队成员,擅长故障分析和性能优化。爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。本文约 1600 字,预计阅读需要 15 分钟。 数据库版本&…
作者:胡呈清,爱可生公司旗下的DBA团队成员,擅长故障分析和性能优化。爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。本文约 1600 字,预计阅读需要 15 分钟。
数据库版本:OceanBase3.2.3.3

案例问题的描述

在关联字段包含组合主键的第1、2、4个字段的一个join查询中。如果执行Nested-Loop Join ,由于被驱动表仅匹配主键的第一、二个字段,虽然成本 cost1 较低,但实际效率不高。此外,驱动表的扇出 n(即输出行数)的估算值远小于实际值。在计算总成本时:

Join 总成本 ≈(驱动表成本 + n*cost1)

在本文所举的例子中,驱动表的成本是不变的,执行计划中 n 的估算值为 5000,但实际值为 60 万,cost1=154。n*cost1 在计算成本时远小于实际值。因此,优化器基于低估的n值选择了 Nested-Loop Join,由于被驱动表只能匹配主键的前两个字段,效率较低,导致整个查询时间耗费较多,但如果被驱动表能匹配主键的全部字段,效率会很高。

分析过程

1. 分析执行计划

问题 SQL 如下(执行耗时 500s+):

selectcount(*) from (SELECTJGBM AS QYDJID,SEGMENT3 AS FNUMBER,PERIOD_NAME AS SSQJ,...FROM(SELECT...FROMDC_ACCOUNTBALANCE_TEMP A,DEF_ACCOUNTCONFIG B,DC_ACCOUNT C,NVAT_ACCANDTAXIDMAPFORP07 D,BI_CHOICEOFUNIT EWHEREA.SEGMENT1 = D.ZTJGBMAND D.SBDWID = E.SBDWIDAND B.JGBM = E.DEPTCODEAND B.YXQSNY <= (substr(A.PERIOD_NAME, 4, 6) || substr(A.PERIOD_NAME, 1, 2))AND (substr(A.PERIOD_NAME, 4, 6) || substr(A.PERIOD_NAME, 1, 2)) <= B.YXJZNYAND C.QYDJID = B.SYZTAND C.FNUMBER = A.SEGMENT3AND C.ACCOUNTYEAR = substr(A.PERIOD_NAME, 4, 6)AND a.period_name = '10-2023') SUBGROUP BYJGBM,SEGMENT3,PERIOD_NAME
) X 
left join DC_ACCOUNTBALANCE A 
ON (A.SSQJ = X.SSQJAND A.QYDJID = X.QYDJIDAND A.FNUMBER = X.FNUMBER
);

执行计划如下(多余信息已删除),结合 SQL 内容进行解读:

  • X 表是 A、B、C、D、E 等 5 张表关联的结果,然后与 A 表进行关联查询。从执行计划看,主要成本在 X 表,因此先执行 X 部分确认是否慢在这部分,执行耗时只要 5 秒,结果有 61 万行,但执行计划中估行只有 5123。
  • X 部分很快,慢在 A 部分,因为是 Nested-Loop Join,A 作为被驱动表会循环查询 61万次(batch_join=false),每次查询走主键,执行计划13号算子中 range_key([A.SSQJ(0x7eb5a42ec400)], [A.QYDJID(0x7eb5a42ed840)], [A.DATAUSE(0x7ec8f84434e0)], [A.FNUMBER(0x7eb5a42eec80)]), range(MIN ; MAX) 部分信息说明索引里有 4个字段,但是range_cond([A.SSQJ(0x7eb5a42ec400) = ?(0x7ec8f8451e20)], [A.QYDJID(0x7eb5a42ed840) = ?(0x7ec8f8452950)])这部分表示只能用到索引的前两个字段,这会是慢的原因吗?有个信息可以提供佐证:A:table_rows:32310843, physical_range_rows:391, logical_range_rows:391 优化器估算A表每次查询需要扫描 391 行,这个效率确实是不高的。
  • 在估算 Nested-Loop Join 的总成本时,计算逻辑是驱动表的成本+驱动表的扇出*\被驱动表查询一次的成本,这个 SQL 中驱动表的扇出(5123)比实际值(61 万)小很多,估算出的总成本比实际小很多。
=================================================================================
|ID|OPERATOR               |NAME                              |EST. ROWS|COST   |
---------------------------------------------------------------------------------
|0 |SCALAR GROUP BY        |                                  |1        |3947739|
|1 | NESTED-LOOP OUTER JOIN|                                  |5123     |3947543|
|2 |  SUBPLAN SCAN         |X                                 |5123     |3154937|
|3 |   HASH GROUP BY       |                                  |5123     |3154861|
|4 |    HASH JOIN          |                                  |5123     |3149203|
|5 |     TABLE SCAN        |C                                 |81314    |31453  |
|6 |     HASH JOIN         |                                  |63573    |2940900|
|7 |      HASH JOIN        |                                  |1898     |35447  |
|8 |       TABLE SCAN      |D(IDX_ACCANDTAXIDMAPFORP07_CMB1)  |2011     |778    |
|9 |       HASH JOIN       |                                  |1736     |32462  |
|10|        TABLE SCAN     |E(IDX_BI_CHOICEOFUNIT_CMB1)       |1704     |660    |
|11|        TABLE SCAN     |B                                 |29154    |11277  |
|12|      TABLE SCAN       |A(IDX_DC_ACCOUNTBALANCE_TEMP_TEST)|639387   |2468263|
|13|  TABLE SCAN           |A                                 |1        |154    |
=================================================================================Outputs & filters: 
-------------------------------------...13 - output([remove_const(1)(0x7ec8f846ba40)]), filter([A.FNUMBER(0x7eb5a42eec80) = ?(0x7ec8f8453480)]), access([A.FNUMBER(0x7eb5a42eec80)]), partitions(p0), is_index_back=false, filter_before_indexback[false], range_key([A.SSQJ(0x7eb5a42ec400)], [A.QYDJID(0x7eb5a42ed840)], [A.DATAUSE(0x7ec8f84434e0)], [A.FNUMBER(0x7eb5a42eec80)]), range(MIN ; MAX), range_cond([A.SSQJ(0x7eb5a42ec400) = ?(0x7ec8f8451e20)], [A.QYDJID(0x7eb5a42ed840) = ?(0x7ec8f8452950)])Used Hint:
...Optimization Info:
-------------------------------------
...
A:table_rows:32310843, physical_range_rows:391, logical_range_rows:391, index_back_rows:0, output_rows:0, est_method:local_storage, optimization_method=cost_based, avaiable_index_name[DC_ACCOUNTBALANCE],...

2. 分析表的统计信息

上一步我们分析得出:X 部分查询很快,慢在 A 表查询,要查询 61 万次。A 表查询时使用了主键的前两个字段,因此需要分析一下 A 表的统计信息,主键的 4 个字段的 NDV 分别是多少,结果如下:

  • SSQJ、QYDJID 两个字段的 NDV 并不高,每组值的重复次数可以通过统计信息估算:32310843/(85*972)=391,这个就是执行计划中的 physical_range_rows:391,意思就是每次查询大概要扫 391 行数据,这个效率如果只执行一次是没啥问题的,但这个 SQL 里需要执行 61 万次,总耗时就大了。
  • 另外 SQL 中关联字段包含了主键的 3 个字段,不在条件里的第 3 个字段 DATAUSE 实际值都为 1,从逻辑上来看,SQL 中加上 AND A.DATAUSE = 1 条件的结果不会变,这样的好处是 A 表查询时可以使用主键的所有字段,每次只需要扫 1 行数据,效率会高很多。另一种更好的方式是主键中去掉 DATAUSE 字段,不过 OB 不支持修改主键。
--查询
select column_name,num_distinct from all_tab_col_statistics where table_name='DC_ACCOUNTBALANCE';
--结果
column_name        num_distinct
SSQJ                85
QYDJID              972
DATAUSE             1
FNUMBER             2616

3. 改写

方法 1:加 AND A.DATAUSE = 1

加条件后,SQL 耗时从 500 秒降到 8 秒,执行计划如下,A 表每次只要扫描 1 行:

=================================================================================
|ID|OPERATOR               |NAME                              |EST. ROWS|COST   |
---------------------------------------------------------------------------------
|0 |SCALAR GROUP BY        |                                  |1        |3214924|
|1 | NESTED-LOOP OUTER JOIN|                                  |5123     |3214729|
|2 |  SUBPLAN SCAN         |X                                 |5123     |3154937|
|3 |   HASH GROUP BY       |                                  |5123     |3154861|
|4 |    HASH JOIN          |                                  |5123     |3149203|
|5 |     TABLE SCAN        |C                                 |81314    |31453  |
|6 |     HASH JOIN         |                                  |63573    |2940900|
|7 |      HASH JOIN        |                                  |1898     |35447  |
|8 |       TABLE SCAN      |D(IDX_ACCANDTAXIDMAPFORP07_CMB1)  |2011     |778    |
|9 |       HASH JOIN       |                                  |1736     |32462  |
|10|        TABLE SCAN     |E(IDX_BI_CHOICEOFUNIT_CMB1)       |1704     |660    |
|11|        TABLE SCAN     |B                                 |29154    |11277  |
|12|      TABLE SCAN       |A(IDX_DC_ACCOUNTBALANCE_TEMP_TEST)|639387   |2468263|
|13|  TABLE GET            |A                                 |1        |11     |
=================================================================================
Outputs & filters: 
...
13 - output([remove_const(1)(0x7eb91646c790)]), filter(nil), access([A.SSQJ(0x7eb91646b730)]), partitions(p0), is_index_back=false, range_key([A.SSQJ(0x7eae68cec980)], [A.QYDJID(0x7eae68ceddc0)], [A.DATAUSE(0x7eae68cf05d0)], [A.FNUMBER(0x7eae68cef200)]), range(MIN ; MAX), range_cond([A.DATAUSE(0x7eae68cf05d0) = 1(0x7eae68cefeb0)], [A.SSQJ(0x7eae68cec980) = ?(0x7eb916451ce0)], [A.QYDJID(0x7eae68ceddc0) = ?(0x7eb916452810)], [A.FNUMBER(0x7eae68cef200) = ?(0x7eb916453340)])
...
Optimization Info:
-------------------------------------
A:table_rows:32310843, physical_range_rows:1, logical_range_rows:1, index_back_rows:0, output_rows:1, est_method:local_storage, optimization_method=rule_based, heuristic_rule=unique_index_without_indexback

改写 2:加 Hint 走 Hash Join

前面我们分析 A 表查询只能使用主键索引的前 2 个字段,效率不高,这种情况下可以看下 Hash Join 的执行效率,加 hint /*+ leading(X A) use_hash(A) */ 耗时只要 40 秒。执行计划如下,结合前面的分析进行解读:

被驱动表 A 除了关联条件没有其他条件,要做全表扫描,成本很高,所以总成本也很高,并且显然比 Nested-Loop Join 的成本高,在没有 Hint 干预的情况下,优化器会选 Nested-Loop Join。

总结

这是一个很经典的问题:如果Join 时关联表太多,执行计划容易选错。

原因是估算驱动表的扇出很容易产生误差,尤其 Join 的结果作为驱动表时,相当于要估算 Join 的结果有多少行,这个误差会更大。而优化器在估算 Nested-Loop Join 算法的成本逻辑中,驱动表的扇出对计算结果影响很大,也就是说 Nested-Loop Join 的成本估算结果很容易产生误差,所以执行计划容易选错。

http://www.yayakq.cn/news/650856/

相关文章:

  • 网站后天添加文章不显示网站做推广有用
  • 青岛市蓝色经济区建设官方网站网店美工考试试题及答案
  • 旺道seo怎么优化网站免费的oa办公系统排名
  • 请描述网站开发的一般流程北京财优化
  • 网站开发交接协议书手机设计软件拉图
  • 建设婚纱摄影网站的重要性室内设计学校哪些
  • 深圳高品质网站建设服务wordpress手机版怎么注册
  • 需要企业网站开发关键词排名怎样
  • wordpress 站中站ppt模板免费整套下载
  • 公司的企业诚信建设分析seo 合理的网站结构
  • ios手机网站建设手机照片制作成相册
  • 中学网站建设书深圳网络营销培训
  • 个人网站 虚拟主机网站上传后后台进不去
  • 苏宁电器网站建设特点分析小程序开发小程序制作
  • 网站建设公司做销售前景好不好?wordpress 分类 php
  • 深圳网站建设电话邢台seo公司
  • 横沥仿做网站做相册的网站(网易
  • 门户网站建设自查报告会网站开发学UI
  • 餐饮手机微网站怎么做免费网站软件下载大全2018
  • 十八个免费的舆情网站wordpress云主机年付5美元
  • 基于mvc4商务网站开发做孝道的网站的目的
  • 开发网站培训班zencart官方网站
  • 房地产网站建设网业协同是什么意思
  • 网站变灰色南京网站制作哪家好
  • 深圳做网站建设产品营销方案策划
  • 盐城网站建设制作方案专门做化妆品的网站
  • 宁波外贸网站制作公司发帖推广百度首页
  • 有的网站打不开是什么原因班级优化大师免费下载
  • 新手学做网站 电子书外贸做网站建设哪家好
  • 网站开发与设计岗位中国品牌网站官网