一条SQL语句查询块分解及查询转换

简介: 原始语句如下: select BIZ_NO,        OUT_BIZ_NO,        ORDER_NO,        USER_ID,        user_name,        CARD_NO,        ACCOUNT_...
原始语句如下:
select BIZ_NO,
       OUT_BIZ_NO,
       ORDER_NO,
       USER_ID,
       user_name,
       CARD_NO,
       ACCOUNT_NO,
       ACCOUNT_BIZ_NO,
       USER_TYPE,
       EVENT,
       GID,
       TRADE_AMOUNT,
       DATA_BIZ_TYPE,
       DIRECTION,
       DATA_STATUS,
       CURRENCY,
       ACCOUNT_DAY,
       COUNTER_PARTY_USER_ID,
       counter_party_user_name,
       COUNTER_PARTY_CARD_NO,
       COUNTER_PARTY_ACCOUNT_NO,
       product_code,
       category,
       origin,
       TRADE_TYPE,
       TRADE_BIZ_PRODUCT_CODE,
       MERCHANT_USER_ID,
       MERCHANT_CARD_NO,
       MERCHANT_ACC_NO,
       MERCHANT_ORDER_BIZ_NO,
       INLET,
       TRADE_FROM,
       BIZ_IDENTITY,
       bank_Code,
       BANK_ACCOUNT_NO,
       BANK_ACCOUNT_NAME,
       CREATE_TIME,
       FINISHED_TIME,
       TRADE_NAME,
       TRADE_MEMO,
       BANK_CNAPS_NO,
       BANK_NAME,
       SETTLE_BIZ_NO,
       SETTLE_CHANNEL_API,
       settle_time,
       relation_no,
       retention_bank_no,
       retention_bank_code,
       refund_reason,
       EXTEND_CONTEXT,
       RAW_ADD_TIME,
       RAW_UPDATE_TIME,
       MEMO,
       relation_time
  from silverb.USER_TRANS_LOG
 where 1 = 1
   AND event = 'CHARGE'
   AND ORDER_NO in
       (select AA.OUT_BIZ_NO
          from (SELECT a.*, ROWNUM RN
                  from (select OUT_BIZ_NO
                          from (select t.event || t.direction as EVENTINOUT,
                                       t.*
                                  from silverb.USER_TRANS_LOG t) X
                         where 1 = 1
                           and X.DATA_BIZ_TYPE in
                               ('FAST_PAY',
                                'TRANSFER',
                                'REMITTANCE',
                                'CARDTOCARD',
                                'ESCROWTRADE',
                                'EBANK',
                                'OFFLINE',
                                'DEDUCT',
                                'QUICK',
                                'CERTIFY',
                                'VERIFY',
                                'WITHDRAW_SINGLE',
                                'WITHDRAW_FORCEING',
                                'WITHDRAW_OFFLINE',
                                'DEPOSITBACK')
                           and X.eventinout in ('DEPOSITBACKIN',
                                                'WITHDRAW_FLUSHES_WRITEOFFOUT',
                                                'DEPOSIT_FLUSHES_FILLACCOUNTSIN',
                                                'TRADE_SHARE_REFUNDOUT',
                                                'TRADE_REFUNDOUT',
                                                'WITHDRAW_FLUSHES_FILLACCOUNTSOUT',
                                                'TRADE_FLUSHES_WRITEOFFOUT',
                                                'WITHDRAWOUT',
                                                'DISHONOUROUT',
                                                'DEPOSITIN',
                                                'TRADE_FLUSHES_FILLACCOUNTSOUT',
                                                'DEPOSITBACK_FLUSHES_WRITEOFFIN',
                                                'DEPOSIT_FLUSHES_WRITEOFFIN',
                                                'DEPOSITBACK_FLUSHES_FILLACCOUNTSIN',
                                                'TRADEOUT')
                           and X.event not in ('TRADE_SHARE', 'CHARGE')
                           and X.MERCHANT_USER_ID = '20140730020001144381'
                           and X.create_time >=
                               to_date('2015-01-01 00:00:00',
                                       'yyyy-mm-dd hh24:mi:ss')
                           and X.create_time                                to_date('2015-02-18 23:59:59',
                                       'yyyy-mm-dd hh24:mi:ss')
                         order by create_time desc) a
                 where ROWNUM          where RN >= 1)
   and DIRECTION = 'OUT'
   and create_time >=
       to_date('2015-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
   and create_time        to_date('2015-03-18 23:59:59', 'yyyy-mm-dd hh24:mi:ss')

执行计划
----------------------------------------------------------------------------------------------------
| Id  | Operation                                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                            |                |       |       |   470 (100)|          |       |       |
|   1 |  NESTED LOOPS                               |                |       |       |            |          |       |       |
|   2 |   NESTED LOOPS                              |                |     8 |  4152 |   470   (7)| 00:00:01 |       |       |
|   3 |    VIEW                                     | VW_NSO_1       |     8 |   336 |   253   (9)| 00:00:01 |       |       |
|   4 |     HASH UNIQUE                             |                |     8 |   120 |            |          |       |       |
|*  5 |      VIEW                                   |                |     8 |   120 |   253   (9)| 00:00:01 |       |       |
|*  6 |       COUNT STOPKEY                         |                |       |       |            |          |       |       |
|   7 |        VIEW                                 |                |     8 |   152 |   253   (9)| 00:00:01 |       |       |
|*  8 |         SORT ORDER BY STOPKEY               |                |     8 |   552 |   253   (9)| 00:00:01 |       |       |
|   9 |          PARTITION RANGE ITERATOR           |                |     8 |   552 |   252   (9)| 00:00:01 |    34 |    33 |
|  10 |           PARTITION HASH ALL                |                |     8 |   552 |   252   (9)| 00:00:01 |     4 |     1 |
|* 11 |            TABLE ACCESS BY LOCAL INDEX ROWID| USER_TRANS_LOG |     8 |   552 |   252   (9)| 00:00:01 |
|* 12 |             INDEX RANGE SCAN                | ME_L_IND       |  1770 |       |    27  (12)| 00:00:01 |   136 |    12
|  13 |    PARTITION RANGE ITERATOR                 |                |     1 |       |    25   (4)| 00:00:01 |    33 |    35 
|  14 |     PARTITION HASH ALL                      |                |     1 |       |    25   (4)| 00:00:01 |     1 |     4 |
|* 15 |      INDEX RANGE SCAN                       | ORDER_L_IND    |     1 |       |    25   (4)| 00:00:01 |   129 |   
|* 16 |   TABLE ACCESS BY LOCAL INDEX ROWID         | USER_TRANS_LOG |     1 |   477 |    27   (4)| 00:00:0
----------------------------------------------------------------------------------------------------


Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------


   1 - SEL5DA710D33SEL683B0107 / VW_NSO_1@SEL5DA710D34SEL683B0107
   5 - SEL3/AA@SEL2
   6 - SEL37SEL7286615E / A@SEL38SEL7286615E
  11 - SEL7286615E/T@SEL5
  12 - SEL7286615E/T@SEL5
  15 - SEL5DA710D3/USERTRANSLOG@SEL1
  16 - SEL5DA710D3/USERTRANSLOG@SEL1
  
Predicate Information (identified by operation id):
---------------------------------------------------


   5 - filter("RN">=1)
   6 - filter(ROWNUM    8 - filter(ROWNUM   11 - filter(("T"."EVENT"'CHARGE' AND ("T"."EVENT"||"T"."DIRECTION"='DEPOSITBACKIN' OR
              "T"."EVENT"||"T"."DIRECTION"='WITHDRAW_FLUSHES_WRITEOFFOUT' OR
              "T"."EVENT"||"T"."DIRECTION"='DEPOSIT_FLUSHES_FILLACCOUNTSIN' OR "T"."EVENT"||"T"."DIRECTION"
              OR "T"."EVENT"||"T"."DIRECTION"='TRADE_REFUNDOUT' OR "T"."EVENT"||"T"."DIRECTION"='WITHDRAW_F
              OR "T"."EVENT"||"T"."DIRECTION"='TRADE_FLUSHES_WRITEOFFOUT' OR "T"."EVENT"||"T"."DIRECTION"='
              "T"."EVENT"||"T"."DIRECTION"='DISHONOUROUT' OR "T"."EVENT"||"T"."DIRECTION"='DEPOSITIN' OR
              "T"."EVENT"||"T"."DIRECTION"='TRADE_FLUSHES_FILLACCOUNTSOUT' OR
              "T"."EVENT"||"T"."DIRECTION"='DEPOSITBACK_FLUSHES_WRITEOFFIN' OR
              "T"."EVENT"||"T"."DIRECTION"='DEPOSIT_FLUSHES_WRITEOFFIN' OR
              "T"."EVENT"||"T"."DIRECTION"='DEPOSITBACK_FLUSHES_FILLACCOUNTSIN' OR "T"."EVENT"||"T"."DIRECT
              INTERNAL_FUNCTION("T"."DATA_BIZ_TYPE") AND "T"."CREATE_TIME"               "T"."EVENT"'TRADE_SHARE'))
  12 - access("T"."MERCHANT_USER_ID"='20140730020001144381')
  15 - access("ORDER_NO"="OUT_BIZ_NO")
  16 - filter(("EVENT"='CHARGE' AND "DIRECTION"='OUT' AND "CREATE_TIME"
  


分解:
1、T@SEL5(T5)selectt.event||t.directionasEVENTINOUT,t.fromsilverb.USERTRANSLOGt2X@SEL4(别名为X的查询块4)虽然执行计划中没有出现这个查询块,但是在10053TRACE是有的,其实他是做的视图合并的结果
select OUT_BIZ_NO from (子查询块T) where X.DATA_BIZ_TYPE in('FAST_PAY',...)
and X.eventinout in ('DEPOSITBACKIN',...)
and X.event not in ('TRADE_SHARE', 'CHARGE')
and X.MERCHANT_USER_ID = '20140730020001144381'
and X.create_time >=to_date('2015-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss')
and X.create_time order by create_time desc
3、EL7286615E10053Registeredqb:SEL7286615E 0x5924a390 (VIEW MERGE SEL4;SEL5)
4、A@SEL3(A3)SELECTa.,ROWNUMRNfrom(X)awhereROWNUM5AA@SEL2(别名为AA的查询块2)
select AA.OUT_BIZ_NO from (子查询块A) AA where RN >= 1
6、SEL683B0107使DISTINCT(AA.OUTBIZNO)AA@SEL2中的AA.OUT_BIZ_NO
这一点从执行计划中的HASH UNIQUE也得到了验证
10053 中明确标示
SU:   Transform an ANY subquery to semi-join or distinct.
SEL683B01070x58e85660(SUBQINTOVIEWFORCOMPLEXUNNESTSEL2)
7、USER_TRANS_LOG@SEL1(A1)selectBIZNO,...fromsilverb.USERTRANSLOGwhere1=1ANDevent=CHARGEANDORDERNOin(A)andDIRECTION=OUTandcreatetime>=todate(2015010100:00:00,yyyymmddhh24:mi:ss)andcreatetime8SEL5DA710D3 此查询块,名字为数据库自动生成,表示进行子查询展开的查询块,此处将
子查询ORDER_NO in (子查询块A)转换NEST LOOP的方式进行
10053 中明确标示
SEL5DA710D30x591f6a80(SUBQUERYUNNESTSEL1; SEL2)[FINAL]1T@SEL5和X@SEL4EL7286615E,对应执行计划的8-12步,并且A@SEL3ROWNUMSORTORDERBYSTOPKEYVIEW2@SEL3不能进行视图合并,因为包含了ROWNUM,对应执行计划的6-7步,使用到谓词ROWNUM 3、查询块@SEL2COMPLEXUNNESTSEL683B0107,对应执行计划的4-5步,使用谓词"RN">=1和distinct(AA.OUT_BIZ_NO),形成第三个VIEW(VW_NSO_1)
4、查询块USER_TRANS_LOG@SEL1SEL683B0107最终进行子查询展开得到了最终的查询块SEL5DA710D32NETSLOOPJIONOutlineDataMERGE(@"SEL5")                                                  
UNNEST(@"SEL2")ORACLE数字 的命名方式,数字从1向上递增(来源:基于ORACLE的优化法则)
关于10053中关于查询转换的说明:
10053中的第一部分就列出执行了哪些查询转换其类型也在其中有说明如下
Legend
The following abbreviations are used by optimizer trace.
CBQT - cost-based query transformation
JPPD - join predicate push-down
OJPPD - old-style (non-cost-based) JPPD
FPD - filter push-down
PM - predicate move-around
CVM - complex view merging
SPJ - select-project-join
SJC - set join conversion
SU - subquery unnesting
OBYE - order by elimination
OST - old style star transformation
ST - new (cbqt) star transformation
CNT - count(col) to count(*) transformation
JE - Join Elimination
JF - join factorization
SLP - select list pruning
DP - distinct placement
qb - query block
LB - leaf blocks
DK - distinct keys
LB/K - average number of leaf blocks per key
DB/K - average number of data blocks per key
CLUF - clustering factor
NDV - number of distinct values
Resp - response cost
Card - cardinality
Resc - resource cost
NL - nested loops (join)
SM - sort merge (join)
HA - hash (join)
CPUSPEED - CPU Speed 
IOTFRSPEED - I/O transfer speed
IOSEEKTIM - I/O seek time
SREADTIM - average single block read time
MREADTIM - average multiblock read time
MBRC - average multiblock read count
MAXTHR - maximum I/O system throughput
SLAVETHR - average slave I/O throughput
dmeth - distribution method
  1: no partitioning required
  2: value partitioned
  4: right is random (round-robin)
  128: left is random (round-robin)
  8: broadcast right and partition left
  16: broadcast left and partition right
  32: partition left using partitioning of right
  64: partition right using partitioning of left
  256: run the join in serial
  0: invalid distribution method
sel - selectivity
ptn - partition
目录
打赏
0
0
0
0
91
分享
相关文章
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
163 77
利用 PolarDB PG 版向量化引擎,加速复杂 SQL 查询!完成任务领发财新年抱枕!
利用 PolarDB PG 版向量化引擎,加速复杂 SQL 查询!完成任务领发财新年抱枕!
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
27 1
|
2月前
|
Java使用sql查询mongodb
通过MongoDB Atlas Data Lake或Apache Drill,可以在Java中使用SQL语法查询MongoDB数据。这两种方法都需要适当的配置和依赖库的支持。希望本文提供的示例和说明能够帮助开发者实现这一目标。
57 17
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
SQL做数据分析的困境,查询语言无法回答的真相
SQL 在简单数据分析任务中表现良好,但面对复杂需求时显得力不从心。例如,统计新用户第二天的留存率或连续活跃用户的计算,SQL 需要嵌套子查询和复杂关联,代码冗长难懂。Python 虽更灵活,但仍需变通思路,复杂度较高。相比之下,SPL(Structured Process Language)语法简洁、支持有序计算和分组子集保留,具备强大的交互性和调试功能,适合处理复杂的深度数据分析任务。SPL 已开源免费,是数据分析师的更好选择。
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
133 6
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
391 11
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
517 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
3月前
|
Java使用sql查询mongodb
通过使用 MongoDB Connector for BI 和 JDBC,开发者可以在 Java 中使用 SQL 语法查询 MongoDB 数据库。这种方法对于熟悉 SQL 的团队非常有帮助,能够快速实现对 MongoDB 数据的操作。同时,也需要注意到这种方法的性能和功能限制,根据具体应用场景进行选择和优化。
129 9

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等