【YashanDB知识库】由于hist_head$中analyze time小于tab$中analyze time导致的sql语句执行慢

本文内容来自YashanDB官网,具体内容请见https://www.yashandb.com/newsinfo/7459465.html?templateId=1718516

问题现象

某局点yashandb cpu使用率100%,经线上分析是由于几个sql执行慢,其中一个sql为简单的单行等值绑定变量过滤+排序。

经分析执行计划,相对以前有所变化,走了另外一个索引(效率低)。

问题的风险及影响

sql语句执行慢,客户的业务受到影响。操作系统cpu 100%可能导致宕机。

问题影响的版本

22.2.10.100

问题发生原因

hist_head 中表对应列的 a n a l y z e t i m e 小于 t a b 中表对应列的analyze time小于tab 中表对应列的analyzetime小于tab中表的analyze time,在执行到estColEqualOrNotParam方法时,由于第一个参数colStats为null导致获得默认selectivity(0.04)后退出。而实际选择率为0.00003,相差甚远,优化器最终估算出来的cost不准,选择了错误的执行计划。

解决方法及规避方式

客户现网通过将错误的索引invisiable后规避。

问题分析和处理过程

现网错误的执行计划及估算出来的rows及cost(sql语句中有hint,可以忽略,实际不加hint也走的是这个执行计划):

过滤条件中sub_account_id的选择性很好,表的总数据量为6千万左右,count(distinct)值为200万左右。很明显,上图中执行计划估算出来的rows是明显失真的。

实际正确的执行计划及cost如下(where语句中多了几个predicate,不影响总量本质):

实际优化器在加载列的统计信息用于估算时,如果hist_head 中 a n a l y z e t i m e 小于 t a b 中analyze time小于tab analyzetime小于tab中analyze time,或者hist_head$中没有表中相关列的数据,那么就会用默认的selectivity(0.04)来做过滤条件估算,最终导致执行计划走偏。

经验总结

hist_head 中存放了列的普通统计信息, h i s t g r m 中存放了列的普通统计信息,histgrm 中存放了列的普通统计信息,histgrm中存放了列的直方图信息

### 回答1: 这个错误是因为 `hist()` 函数不能直接处理 `POSIXt` 类型的时间数据。你需要在调用 `hist()` 函数时显式设置参数 `breaks`,来指定时间数据的分割点。例如,你可以使用 `as.numeric()` 函数将时间数据转换为数值型数据,然后再进行直方图的绘制。下面是一个例子: ``` # 将时间数据转换为数值型数据 time_in_seconds <- as.numeric(data$TIME) # 绘制直方图 hist(time_in_seconds, breaks = "hours") ``` 在上面的代码,我们将时间数据转换为秒数,并将 `breaks` 参数设置为 `"hours"`,这意味着将时间数据按照小时进行分割。你可以根据需要修改 `breaks` 参数的值,来得到不同的直方图。 ### 回答2: 这个错误是因为在使用hist函数时,对于类型为POSIXt(日期和时间)的数据,需要设置'breaks'参数来指定数据的分组间隔。hist函数是用于绘制直方图的,它将数据分成不同的区间,并统计每个区间的观测值数量。 当我们使用hist(data$TIME)时,它要求我们指定'breaks'参数来设定分组间隔。'breaks'参数可以是一个整数值,用来确定分组的数量,也可以是一个向量,用来指定每个分组的具体边界值。 举个例子,假设我们有一列时间数据,我们想要将其分成10个等距的时间区间。我们可以使用以下代码来处理: breaks <- seq(min(data$TIME), max(data$TIME), length.out = 11) hist(data$TIME, breaks = breaks) 在这个例子,我们使用seq函数来生成一个包含11个数值的向量,在这个向量,第一个数值是时间数据的最小值,最后一个数值是时间数据的最大值,其余的数值是根据时间数据的范围等距生成的。然后,我们将这个向量作为'breaks'参数传递给hist函数。 通过设定'breaks'参数,我们可以解决hist(data$TIME)函数出现的错误。 ### 回答3: 在R语言,当我们使用hist()函数来绘制直方图时,需要设置一个参数'breaks',该参数指定直方图的分组方式。具体来说,'breaks'参数表示我们希望将数据分成多少个组。如果不设置该参数,直接执行hist(data$TIME),会出现"hist(<POSIXt>)必需设定'breaks'"的错误提示。 为了解决这个错误,我们需要在hist()函数设置'breaks'参数的值。例如,我们可以将数据分为10个组,代码如下: hist(data$TIME, breaks = 10) 这样就可以绘制出带有10个组的直方图了。 当然,我们也可以根据实际情况来调整'breaks'参数的值,以获得更加合适的直方图显示效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值