hash group by后导致的cardinality=1问题

Oracle SQL性能调优
针对Oracle Database 11g中的一条执行缓慢的SQL语句进行性能调优,发现其性能瓶颈在于hash group by操作导致的cardinality估算错误。通过改写SQL语句并物化中间结果到临时表,显著提升了查询效率。
在做报表性能调优的时候发现一条sql执行很慢,发现主要是由于cardinality估算错误导致

数据库版本: Oracle  Database  11g  Enterprise Edition Release 11.2.0.4.0 - 64 bi t Production

 



前一步HASH JOIN后cardinality估算6985,hash group by后竟然变成1,cardinality=1的结果集会导致之后的查询无脑nest loop

分析:个人认为hash group by对cardinality影响应该是group by后估算前一步结果集有多少ndv值,这个值就是这步的cardinality,如下所示
 

 


file:///C:/Users/jinlei/AppData/Local/YNote/data/jinleilanqiu@126.com/7c6af05a027b4af6bc079be4fdca1cc1/clipboard.png
那么针对出问题的sql也是一cpsmq.cn
dnsjd.cn
kqklh.cn
nkyny.cn样的,hash group by后cardinality应该<=6623,出现1过为极端



通过改写语句比较差异:
 
qlypz.cn
wqfpz.cn
wcrfc.cn
yflbb.cn
 
phqxl.cn
cflls.cn
bxykr.cn
qnhnh.cn
 




可以发现连接后将结果集物化到临时表后再group by结果相对正确,将group by 字段等价替换成claimkpcgf.cn
hdgrx.cn
kyxkl.cn
ggmqr.cn
yqtby.cn_id后结果也相对kxpsd.cn
gcqbs.cn
jplzy.cn正确


请问各位大神还能从哪些方面去分析hash group by估算错误的具体原因?
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) File ~\anaconda3\Lib\site-packages\pandas\core\indexes\base.py:3791, in Index.get_loc(self, key) 3790 try: -> 3791 return self._engine.get_loc(casted_key) 3792 except KeyError as err: File index.pyx:152, in pandas._libs.index.IndexEngine.get_loc() File index.pyx:181, in pandas._libs.index.IndexEngine.get_loc() File pandas\_libs\hashtable_class_helper.pxi:7080, in pandas._libs.hashtable.PyObjectHashTable.get_item() File pandas\_libs\hashtable_class_helper.pxi:7088, in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: 'date' The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Cell In[5], line 409 406 print("训练流程完成!") 408 if __name__ == "__main__": --> 409 main() Cell In[5], line 326, in main() 323 positive_samples['label'] = 1 325 # 负样本采样 --> 326 negative_samples = vectorized_negative_sampling( 327 hist_exposure, positive_samples, sample_ratio=0.05 328 ) 330 # 合并数据集 331 click_data = pd.concat([positive_samples, negative_samples], ignore_index=True) Cell In[5], line 130, in vectorized_negative_sampling(exposure, positive_set, sample_ratio) 127 negative_samples['label'] = 0 129 # 添加时间信息(使用最近曝光时间) --> 130 negative_samples['date'] = exposure['date'].max() 132 return negative_samples File ~\anaconda3\Lib\site-packages\pandas\core\frame.py:3893, in DataFrame.__getitem__(self, key) 3891 if self.columns.nlevels > 1: 3892 return self._getitem_multilevel(key) -> 3893 indexer = self.columns.get_loc(key) 3894 if is_integer(indexer): 3895 indexer = [indexer] File ~\anaconda3\Lib\site-packages\pandas\core\indexes\base.py:3798, in Index.get_loc(self, key) 3793 if isinstance(casted_key, slice) or ( 3794 isinstance(casted_key, abc.Iterable) 3795 and any(isinstance(x, slice) for x in casted_key) 3796 ): 3797 raise InvalidIndexError(key) -> 3798 raise KeyError(key) from err 3799 except TypeError: 3800 # If we have a listlike key, _check_indexing_error will raise 3801 # InvalidIndexError. Otherwise we fall through and re-raise 3802 # the TypeError. 3803 self._check_indexing_error(key) KeyError: 'date'
最新发布
07-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值