一个通过添加本地分区索引提高SQL性能的案例
今天接到同事求助,说有一个select query,在Oracle上要跑一分多钟,他希望能在5s内出结果,该sql如下:
- Select /*+ parallel(src, 8) */ distinct
- src.systemname as systemname
- , src.databasename as databasename
- , src.tablename as tablename
- , src.username as username
- from <strong>meta_dbql_table_usage_exp_hst</strong> src
- inner <strong>join DR_QRY_LOG_EXP_HST</strong> rl on
- <strong>src.acctstringdate = rl.acctstringdate
- and src.queryid = rl.queryid</strong>
- And Src.Systemname = Rl.Systemname
- and src.acctstringdate > sysdate - 30
- And Rl.Acctstringdate > Sysdate - 30
- inner join <strong>meta_dr_qry_log_tgt_all_hst </strong>tgt on
- upper(tgt.systemname) = upper('MOZART')
- And Upper(tgt.Databasename) = Upper('GDW_TABLES')
- And Upper(tgt.Tablename) = Upper('SSA_SLNG_LSTG_MTRC_SD')
- <strong>AND src.acctstringdate = tgt.acctstringdate
- and rl.statement_id = tgt.statement_id</strong>
- and rl.systemname = tgt.systemname
- And Tgt.Acctstringdate > Sysdate - 30
- And Not(
- Upper(Tgt.Systemname)=Upper(src.systemname)
- And
- Upper(Tgt.Databasename) = Upper(Src.Databasename)
- And
- Upper(Tgt.Tablename) = Upper(Src.Tablename)
- )
- And tgt.Systemname is not null
- And tgt.Databasename Is Not Null
- And tgt.tablename is not null
- ;
SQL的简单分析
- ------------------------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
- ------------------------------------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 159 | 8654 | | |
- | 1 | PX COORDINATOR | | | | | | |
- | 2 | PX SEND QC (RANDOM) | :TQ10002 | 1 | 159 | 8654 | | |
- | 3 | SORT UNIQUE | | 1 | 159 | 8654 | | |
- | 4 | PX RECEIVE | | 1 | 36 | 3 | | |
- | 5 | PX SEND HASH | :TQ10001 | 1 | 36 | 3 | | |
- |* 6 | TABLE ACCESS BY LOCAL INDEX ROWID| DR_QRY_LOG_EXP_HST | 1 | 36 | 3 | | |
- | 7 | NESTED LOOPS | | 1 | 159 | 8633 | | |
- | 8 | NESTED LOOPS | | 8959 | 1076K| 4900 | | |
- | 9 | BUFFER SORT | | | | | | |
- | 10 | PX RECEIVE | | | | | | |
- | 11 | PX SEND BROADCAST | :TQ10000 | | | | | |
- | 12 | PARTITION RANGE ITERATOR | | 1 | 56 | 4746 | KEY | 14 |
- |* 13 | TABLE ACCESS FULL | META_DR_QRY_LOG_TGT_ALL_HST | 1 | 56 | 4746 | KEY | 14 |
- | 14 | PX BLOCK ITERATOR | | 8959 | 586K| 154 | KEY | KEY |
- |* 15 | TABLE ACCESS FULL | META_DBQL_TABLE_USAGE_EXP_HST | 8959 | 586K| 154 | KEY | KEY |
- | 16 | PARTITION RANGE ITERATOR | | 1 | | 2 | KEY | KEY |
- |* 17 | INDEX RANGE SCAN | DR_QRY_LOG_EXP_HST_IDX | 1 | | 2 | KEY | KEY |
- ------------------------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 6 - filter("RL"."STATEMENT_ID"="TGT"."STATEMENT_ID" AND "RL"."SYSTEMNAME"="TGT"."SYSTEMNAME" AND "SRC"."SYSTEMNAME"="RL"."SYSTEMNAME")
- 13 - filter(UPPER("TGT"."SYSTEMNAME")='MOZART' AND UPPER("TGT"."DATABASENAME")='GDW_TABLES' AND
- UPPER("TGT"."TABLENAME")='SSA_SLNG_LSTG_MTRC_SD' AND "TGT"."ACCTSTRINGDATE">SYSDATE@!-30 AND "TGT"."SYSTEMNAME" IS NOT NULL
- "TGT"."DATABASENAME" IS NOT NULL AND "TGT"."TABLENAME" IS NOT NULL)
- 15 - filter("SRC"."ACCTSTRINGDATE"="TGT"."ACCTSTRINGDATE" AND (UPPER("TGT"."SYSTEMNAME")<>UPPER("SRC"."SYSTEMNAME") OR
- UPPER("TGT"."DATABASENAME")<>UPPER("SRC"."DATABASENAME") OR UPPER("TGT"."TABLENAME")<>UPPER("SRC"."TABLENAME")) AND
- "SRC"."ACCTSTRINGDATE">SYSDATE@!-30)
- 17 - access("SRC"."QUERYID"="RL"."QUERYID" AND "SRC"."ACCTSTRINGDATE"="RL"."ACCTSTRINGDATE")
- filter("RL"."ACCTSTRINGDATE">SYSDATE@!-30)
定位问题
这种连接的好处是内存使用非常少。
如果驱动数据源有限,且被驱动表在连接列上有相应的索引,则这种连接方式才是高效的。
- SQL> select index_name, table_name from user_indexes where table_name in ('DR_QRY_LOG_EXP_HST',upper('meta_dbql_table_usage_exp_hst'), upper('meta_dr_qry_log_tgt_all_hs
- INDEX_NAME TABLE_NAME
- ------------------------------------------------------------ ------------------------------------------------------------
- META_DR_QRY_LOG_TGT_ALL_IDX META_DR_QRY_LOG_TGT_ALL_HST
- META_DBQL_TUSAGE_EHST_IDX META_DBQL_TABLE_USAGE_EXP_HST
- DR_QRY_LOG_EXP_HST_IDX DR_QRY_LOG_EXP_HST
- CREATE INDEX "GV"."META_DR_QRY_LOG_TGT_ALL_IDX" ON "GV"."META_DR_QRY_LOG_TGT_ALL_HST" ("STATEMENT_ID", "ACCTSTRINGDATE")
- CREATE INDEX "GV"."META_DBQL_TUSAGE_EHST_IDX" ON "GV"."META_DBQL_TABLE_USAGE_EXP_HST" ("QUERYID", "ACCTSTRINGDATE")
- CREATE INDEX "GV"."DR_QRY_LOG_EXP_HST_IDX" ON "GV"."DR_QRY_LOG_EXP_HST" ("QUERYID", "ACCTSTRINGDATE")
- create index DR_QRY_LOG_EXP_HST_IDX2 on gv.DR_QRY_LOG_EXP_HST (statement_id,ACCTSTRINGDATE) local;
性能对比
- ------------------------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
- ------------------------------------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 159 | 4838 | | |
- | 1 | SORT UNIQUE | | 1 | 159 | 4838 | | |
- |* 2 | TABLE ACCESS BY LOCAL INDEX ROWID | META_DBQL_TABLE_USAGE_EXP_HST | 1 | 67 | 3 | | |
- | 3 | NESTED LOOPS | | 1 | 159 | 4816 | | |
- | 4 | NESTED LOOPS | | 18 | 1656 | 4762 | | |
- | 5 | PARTITION RANGE ITERATOR | | 1 | 56 | 4746 | KEY | 14 |
- |* 6 | TABLE ACCESS FULL | META_DR_QRY_LOG_TGT_ALL_HST | 1 | 56 | 4746 | KEY | 14 |
- | 7 | PARTITION RANGE ITERATOR | | 18 | 648 | 16 | KEY | 14 |
- |* 8 | TABLE ACCESS BY LOCAL INDEX ROWID| DR_QRY_LOG_EXP_HST | 18 | 648 | 16 | KEY | 14 |
- |* 9 | <strong>INDEX RANGE SCAN | DR_QRY_LOG_EXP_HST_IDX2</strong> | 31 | | 15 | KEY | 14 |
- | 10 | PARTITION RANGE ITERATOR | | 1 | | 2 | KEY | KEY |
- |* 11 | INDEX RANGE SCAN | META_DBQL_TUSAGE_EHST_IDX | 1 | | 2 | KEY | KEY |
- ------------------------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - filter((UPPER("TGT"."SYSTEMNAME")<>UPPER("SRC"."SYSTEMNAME") OR
- UPPER("TGT"."DATABASENAME")<>UPPER("SRC"."DATABASENAME") OR UPPER("TGT"."TABLENAME")<>UPPER("SRC"."TABLENAME"))
- AND "SRC"."SYSTEMNAME"="RL"."SYSTEMNAME")
- 6 - filter(UPPER("TGT"."SYSTEMNAME")='MOZART' AND UPPER("TGT"."DATABASENAME")='GDW_TABLES' AND
- UPPER("TGT"."TABLENAME")='SSA_SLNG_LSTG_MTRC_SD' AND "TGT"."ACCTSTRINGDATE">SYSDATE@!-30 AND "TGT"."SYSTEMNAME"
- IS NOT NULL AND "TGT"."DATABASENAME" IS NOT NULL AND "TGT"."TABLENAME" IS NOT NULL)
- 8 - filter("RL"."SYSTEMNAME"="TGT"."SYSTEMNAME")
- 9 - access("RL"."STATEMENT_ID"="TGT"."STATEMENT_ID" AND "RL"."ACCTSTRINGDATE">SYSDATE@!-30 AND
- "RL"."ACCTSTRINGDATE" IS NOT NULL)
- 11 - access("SRC"."QUERYID"="RL"."QUERYID" AND "SRC"."ACCTSTRINGDATE"="RL"."ACCTSTRINGDATE")
- filter("SRC"."ACCTSTRINGDATE"="TGT"."ACCTSTRINGDATE" AND "SRC"."ACCTSTRINGDATE">SYSDATE@!-30)
从新的的执行计划可以看出,它的第一个NESTED LOOP果然用了最新创建的索引。
- 已用时间: 00: 00: 02.16
方法总结
一个通过添加本地分区索引提高SQL性能的案例相关推荐
- oracle全局索引改成本地索引,解析一个通过添加本地分区索引提高SQL性能的案例...
该sql如下: Select /*+ parallel(src, 8) */ distinct src.systemname as systemname , src.databasename as ...
- [Oracle] 一个通过添加本地分区索引提高SQL性能的案例
今天接到同事求助,说有一个select query,在Oracle上要跑一分多钟,他希望能在5s内出结果,该sql如下: Select /*+ parallel(src, 8) */ distinct ...
- 建立合理的索引提高SQL Server的性能
建立合理的索引提高SQL Server的性能- 标签:索引,性能优化 建立合理的索引提高SQL Server的性能 在应用系统中,尤其在联机事务处理系统中,对数据查询及处理速度已成为衡量应用系统成败的 ...
- 【Oracle】表级别分区操作对索引(本地分区索引,全局分区索引,非分区索引)的影响
--参考自<Oracle索引技术> 先贴上结论吧: 下面对以上几种操作分别测试: 创建测试表及索引 --创建测试分区表 CREATE TABLE employees_parttest (e ...
- oracle全局索引改成本地索引,FAQ : 如何获得 Oracle 分区索引的类型 - 全局分区索引、本地分区索引...
Oracle 数据库针对分区的信息,通过多个数据字典视图来维护,所以在获取信息时,经常会困惑 DBA 们. 例如,如何获取 分区索引的类型,如何判断一个索引,是 全局分区索引,还是本地分区索引? 通过 ...
- dbcc dbreindex server sql_DBCC DBREINDEX重建索引提高SQL Server性能
DBCC DBREINDEX重建索引提高SQL Server性能 [转载]大多数SQL Server表需要索引来提高数据的访问速度,如果没有索引,SQL Server 要进行表格扫描读取表中的每一个记 ...
- 转 五种提高 SQL 性能的方法
提高 SQL 性能的方法 有时, 为了让应用程序运行得更快,所做的全部工作就是在这里或那里做一些很小调整.啊,但关键在于确定如何进行调整!迟早您会遇到这种情况:应用程序中的 SQL 查询不能按照您想要 ...
- 提高sql性能的方法_三种提高T-SQL性能的方法
提高sql性能的方法 介绍 (Introduction) When customers used to ask for advice to solve some T-SQL Problem, they ...
- dbcc dbreindex server sql_DBCC DBREINDEX重建索引提高SQL Server性能
大多数SQL Server表需要索引来提高数据的访问速度,如果没有索引,SQL Server 要进行表格扫描读取表中的每一个记录才能找到索要的数据.索引可以分为簇索引和非簇索引,簇索引通过重排表中的数 ...
最新文章
- linux 树莓派查看ip,树莓派 常用Linux命令
- 【C#食谱】【杭帮菜】菜单2:写一个TCP客户端
- 简单工厂模式、工厂方法模式、抽象工厂模式 之间的对比
- 【Spring实战】注入非Spring Bean对象
- Acwing第 31 场周赛【完结】
- HDR和SDR的区别
- java.lang.IllegalStateException: Not connected to server
- php设置session 生命周期,设置session的生命周期(php)
- Notepad++便签模式
- 可怕!CPU 竟成了黑客的帮凶!
- 蔡工RK系列Android驱动开发入门视频课程
- php中几个操作函数参数的函数func_num_args() func_get_args() func_get_arg($i)php
- 下列关于linux扩展名说法错误的是,全国计算机一级考试选择题集锦(2015年1月)
- Sybase数据库整体迁移纪要
- 偷梁换柱“Windows 11安装包”竟成了恶意程序?
- 单侧上行速度测试软件,20210708-确认 低开单边上行,箱体理论几乎是贯穿a股运行周期的,如果平时容易过分看好行情,或者过分看弱行情,不妨就以最中庸的箱体去验证。... - 雪球...
- Java之BIO网络编程
- mysql表中的ak什么意思_数据库 ak pk
- android打败苹果,苹果iOS打败安卓的另一面:配件多于Android
- YOLOv5剪枝✂️| 模型剪枝实战篇
热门文章
- Jetson nano (4GB B01) 系统安装,官方Demo测试 (目标检测、手势识别)
- sqlserver转mysql_数据库 SQLServer转MySQL数据库
- 已删除的回收站文件恢复方法
- 如何解决C++编译错误C2280尝试引用已删除的函数【每天一个小技巧】
- java通过poi导出excel和pdf
- R语言绘制复杂抽样设计数据cox回归生存曲线(Kaplan-Meier)
- 微波电路中的线性和非线性
- 干货 | 敏捷培训必备小游戏,都在这里了!
- Udesk即时通讯网页插件发送咨询对象(一、使用内嵌代码)
- Jboot 跨域请求