【Oracle专栏】group by 和distinct 效率

Oracle相关文档,希望互相学习,共同进步

风123456789~-CSDN博客


1.背景

查阅资料:

1)有索引情况下,group by和distinct都能使用索引,效率相同。

2)无索引情况下,distinct 效率高于group by。distinct 和 group by都会进行分组操作,但group by可能会进行排序,触发filesort,导致sql执行效率低下。

两者的语法区别在于,distinct 用于返回唯一不同的值,group by 的原理是先对结果进行分组,然后返回每组中的第一条数据,且是根据group by的后接字段进行去重的。

2. 实验

准备表:test_subject_bal 1千万数据

sql 复制代码
select count(*) from test_subject_bal t

2.1 无索引情况下

1)distinct 实验

实验语句:
sql 复制代码
select distinct t.social_credit_code,t.year_month 
      from  test_subject_bal t
      where t.data_flag='M'  --and t.social_credit_code='014011024205200001'
      and not exists(select 1 from validate_dtl_book b 
                     where b.orgno_fz = t.social_credit_code
                     and b.kid = t.book_id)   
结果截图: 11.375s 6.31s 7.108s 6.769s 6.660s
sql语句的执行计划: 125316

2)group by 实验

实验语句:
sql 复制代码
select  t.social_credit_code,t.year_month 
      from  test_subject_bal t
      where t.data_flag='M'  --and t.social_credit_code='014011024205200001'
      and not exists(select 1 from validate_dtl_book b 
                     where b.orgno_fz = t.social_credit_code
                     and b.kid = t.book_id)   
      group by social_credit_code,t.year_month
截图截图:7.458s 6.570s 7.123s 7.041s 6.206s
sql语句的执行计划: 125316

2.2有索引情况下

sql 复制代码
create table test_subject_bal2 as select * from test_subject_bal t;

CREATE INDEX idx_orgno_test_subject_bal2 ON test_subject_bal2 (social_credit_code);
CREATE INDEX idx_ymonth_test_subject_bal2 ON test_subject_bal2 (year_month);

1)distinct 实验

sql语句:
sql 复制代码
select distinct t.social_credit_code,t.year_month 
      from  test_subject_bal2 t
      where t.data_flag='M'  --and t.social_credit_code='014011024205200001'
      and not exists(select 1 from validate_dtl_book b 
                     where b.orgno_fz = t.social_credit_code
                     and b.kid = t.book_id)   
结果截图:7.142s 6.911s 6.867s 7.908s 6.636s
sql执行计划:125319

2)group by 实验

sql语句:
sql 复制代码
select  t.social_credit_code,t.year_month 
      from  test_subject_bal2 t
      where t.data_flag='M'  --and t.social_credit_code='014011024205200001'
      and not exists(select 1 from validate_dtl_book b 
                     where b.orgno_fz = t.social_credit_code
                     and b.kid = t.book_id)   
      group by social_credit_code,t.year_month
结果截图: 6.827s 7.285s 7.415s 6.415s 6.384s
sql执行计划:125319

2.3 有索引情况下,且索引字段是过滤条件的字段

sql 复制代码
CREATE INDEX idx_data_flag_test_subject_bal2 ON test_subject_bal2 (data_flag);

1)distinct 实验

sql语句:
sql 复制代码
select distinct t.social_credit_code,t.year_month 
      from  test_subject_bal2 t
      where t.data_flag='M'  --and t.social_credit_code='014011024205200001'
      and not exists(select 1 from validate_dtl_book b 
                     where b.orgno_fz = t.social_credit_code
                     and b.kid = t.book_id)   
结果截图:6.352s 6.729s 6.242s 6.163s 6.126s
sql执行计划:125319

2)group by实验

sql语句:
sql 复制代码
select  t.social_credit_code,t.year_month 
      from  test_subject_bal2 t
      where t.data_flag='M'  --and t.social_credit_code='014011024205200001'
      and not exists(select 1 from validate_dtl_book b 
                     where b.orgno_fz = t.social_credit_code
                     and b.kid = t.book_id)   
      group by social_credit_code,t.year_month
结果截图:6.304s 6.144s 6.137s 6.144s 6.155s
sql执行计划:125319

3.总结

实验中:表 1千万级别

序号 实验内容 第1次 第2次 第3次 第4次 第5次 sql执行计划 cost 有条件 sql执行计划 cost 无条件
1 distinct实验 无索引 11.375s 6.31s 7.108s 6.769s 6.660s 125316 120964
2 group实验 无索引 7.458s 6.570s 7.123s 7.041s 6.206s 125316 120964
3 distinct实验 有索引 7.142s 6.911s 6.867s 7.908s 6.636s 125319 120967
4 group实验 有索引 6.827s 7.285s 7.415s 6.415s 6.384s 125319 120967
5 distinct实验 条件索引 6.352s 6.729s 6.242s 6.163s 6.126s 125319 120967
6 group实验 条件索引 6.304s 6.144s 6.137s 6.144s 6.155s 125319 120967

分析结果:

加索引在非检索字段,即时有索引 效果也不大,甚至有可能消耗更多资源。

加索引在检索字段,效果有,但是如果表的数据量很大,全表扫描可能仍然比使用索引快。看到执行计划,依然是全表扫描。

常用优化建议:

  • 索引优化‌:确保在查询条件中频繁使用的列上创建适当的索引。
  • 统计信息更新‌:定期更新表和索引的统计信息,以确保优化器能够做出正确的决策。
  • 避免全表扫描‌:尽量通过索引访问表,以减少I/O开销。
  • 查询重写‌:有时通过重写查询语句,可以获得更有效的执行计划。
  • ‌**使用提示(Hints)**‌:在特定情况下,可以使用Oracle提供的提示来影响优化器的决策,但应谨慎使用。

项目管理--相关知识

项目管理-项目绩效域1/2-CSDN博客

项目管理-项目绩效域1/2_八大绩效域和十大管理有什么联系-CSDN博客

项目管理-项目绩效域2/2_绩效域 团不策划-CSDN博客

高项-案例分析万能答案(作业分享)-CSDN博客

项目管理-计算题公式【复习】_项目管理进度计算题公式:乐观-CSDN博客

项目管理-配置管理与变更-CSDN博客

项目管理-项目管理科学基础-CSDN博客

项目管理-高级项目管理-CSDN博客

项目管理-相关知识(组织通用治理、组织通用管理、法律法规与标准规范)-CSDN博客


Oracle其他文档,希望互相学习,共同进步

Oracle-找回误删的表数据(LogMiner 挖掘日志)_oracle日志挖掘恢复数据-CSDN博客

oracle 跟踪文件--审计日志_oracle审计日志-CSDN博客

ORA-12899报错,遇到数据表某字段长度奇怪现象:"Oracle字符型,长度50"但length查却没有50_varchar(50) oracle 超出截断-CSDN博客

EXP-00091: Exporting questionable statistics.解决方案-CSDN博客

Oracle 更换监听端口-CSDN博客

相关推荐
star-keke10 分钟前
Python pip安装依赖redis被自动降级的问题
数据库·redis·pip
卜锦元12 分钟前
Golang后端性能优化手册(第二章:缓存策略与优化)
开发语言·数据库·后端·性能优化·golang
小CC吃豆子20 分钟前
Redis 缓存雪崩
数据库
雪花desu30 分钟前
深入 LangChain LCEL 的 10 个核心特性
数据库·人工智能·深度学习·langchain
沛沛老爹34 分钟前
Web开发者快速上手Advanced RAG:索引优化原理与实践
前端·数据库·advanced rag·深度优化·web转型ai
未来之窗软件服务1 小时前
幽冥大陆(六十五) PHP6.x SSL 文字解密—东方仙盟古法结界
网络·数据库·ssl·加解密·仙盟创梦ide·东方仙盟
云边有个稻草人1 小时前
金仓数据库MongoDB兼容:核心技术支撑国产化替代落地
数据库·mongodb·国产数据库·金仓数据库·kes
几度风雨见丹心1 小时前
sqlite图形化界面建数据库、建表、增删改查、选择.db文件、将sql脚本一键导入,并同步数据、一键导出sql脚本并保存本地.sql文件
数据库·sql·sqlite
杰克尼1 小时前
mysql_day03总结
数据库·mysql
qq_229058011 小时前
Django学习笔记
数据库·sqlite