现在的位置: 首页 > 综合 > 正文

10053事件的妙用

2014年08月01日 ⁄ 综合 ⁄ 共 6003字 ⁄ 字号 评论关闭

       前些天有一个奇怪的现象,一条SQL语句不加order by是可以查出10条数据,加了order by后一条数据都查不出来。
      用的oracle版本是10.0.1。由于所用的表不能贴出来,所以只能跟大家讲讲思路。
      看此条SQL比较复杂,多层嵌套,有肉眼真是看不出来是什么问题,但是我有思路。因为我知道Oracle会对SQL进行查询转换,如in(1,2)会改为or等。所以我决定用10053事件看看两条SQL被转换成什么样了。

      trace出来文件后,找到此条SQL的执行计划上的第一个******* UNPARSED QUERY IS *******,这个便是经过查询转换后的SQL语句。
      trace出来的结果是两条SQL转换出来的查询语句大相径庭,最后改了一个子查询的写法,order by终于可以出数据了。

 原始SQL:
SELECT *
  FROM (SELECT *
          FROM (SELECT INNER_TABLE.*, ROWNUM OUTER_TABLE_ROWNUM
                  FROM (SELECT  dg_730.GG_RESERVE_SCHEME_ITEM.RESERVE_LEVEL
                          FROM dg_730.GG_RESERVE_QUOTA ,
                               dg_730.GG_RESERVE_QUOTA_ITEM,
                               (SELECT T.RESERVE_SCHEME_ITEM_ID,
                                       T.RESERVE_QUOTA_ITEM_ID
                                  FROM dg_730.GG_RESERVE_SCHEME_RELATION T
                                 WHERE T.RELATION_ID =
                                       (SELECT MAX(T1.RELATION_ID)
                                          FROM dg_730.GG_RESERVE_SCHEME_RELATION T1
                                         WHERE T.RESERVE_QUOTA_ITEM_ID =
                                               T1.RESERVE_QUOTA_ITEM_ID)) SR,
                               dg_730.GG_RESERVE_SCHEME_ITEM,
                               dg_730.GG_RESERVE_SCHEME
                         WHERE dg_730.GG_RESERVE_QUOTA.RESERVE_QUOTA_ID =
                               dg_730.GG_RESERVE_QUOTA_ITEM.RESERVE_QUOTA_ID
                           AND dg_730.GG_RESERVE_QUOTA_ITEM.RESERVE_QUOTA_ITEM_ID =
                               SR.RESERVE_QUOTA_ITEM_ID
                           AND SR.RESERVE_SCHEME_ITEM_ID =
                               dg_730.GG_RESERVE_SCHEME_ITEM.RESERVE_SCHEME_ITEM_ID
                           AND dg_730.GG_RESERVE_SCHEME.RESERVE_SCHEME_ID =
                               dg_730.GG_RESERVE_SCHEME_ITEM.RESERVE_SCHEME_ID
                           AND dg_730.GG_RESERVE_QUOTA_ITEM.STATUS IN
                               ('schemed' , 'noScheme'  , 'disabled')
                           AND dg_730.GG_RESERVE_QUOTA.PREPARE_DEPARTMENT_ID =
                               '1030000003'
                             AND dg_730.GG_RESERVE_QUOTA_ITEM.RESERVE_MATERIAL_TYPE=37
                           AND dg_730.GG_RESERVE_QUOTA.RESERVE_LEVEL= '1'
                           ORDER
BY RESERVE_SCHEME_NAME desc
 --加了这个,出不来数据
                     ) INNER_TABLE)
         WHERE OUTER_TABLE_ROWNUM <= 18) OUTER_TABLE
WHERE OUTER_TABLE_ROWNUM > 0


  这是trace处理的两条SQL:
SELECT /*+ */
"from$_subquery$_002"."OUTER_TABLE_ROWNUM"    "OUTER_TABLE_ROWNUM"
  FROM (SELECT /*+ */
         "INNER_TABLE"."ORIGINAL_MATERIAL_ID"  "ORIGINAL_MATERIAL_ID",
         ROWNUM                                "OUTER_TABLE_ROWNUM"
          FROM (SELECT /*+ */
                 "SYS_ALIAS_1"."RELATION_ID"                     "RELATION_ID"
                  FROM "DG__730"."GG_RESERVE_QUOTA"           "GG_RESERVE_QUOTA",
                       "DG__730"."GG_RESERVE_QUOTA_ITEM"      "GG_RESERVE_QUOTA_ITEM",
                       "DG__730"."GG_RESERVE_SCHEME_RELATION" "SYS_ALIAS_1",
                       "DG__730"."GG_RESERVE_SCHEME_ITEM"     "GG_RESERVE_SCHEME_ITEM",
                       "DG__730"."GG_RESERVE_SCHEME"          "GG_RESERVE_SCHEME"
                 WHERE "GG_RESERVE_QUOTA"."PREPARE_DEPARTMENT_ID" =
                       1030000003
                   AND "GG_RESERVE_QUOTA"."RESERVE_LEVEL" = 1
                   AND "GG_RESERVE_QUOTA"."RESERVE_QUOTA_ID" =
                       "GG_RESERVE_QUOTA_ITEM"."RESERVE_QUOTA_ID"
                   AND "GG_RESERVE_QUOTA_ITEM"."RESERVE_MATERIAL_TYPE" = 37
                   AND ("GG_RESERVE_QUOTA_ITEM"."STATUS" = 'disabled' OR
                       "GG_RESERVE_QUOTA_ITEM"."STATUS" = 'noScheme' OR
                       "GG_RESERVE_QUOTA_ITEM"."STATUS" = 'schemed')
                   AND "GG_RESERVE_QUOTA_ITEM"."RESERVE_QUOTA_ITEM_ID" =
                       "SYS_ALIAS_1"."RESERVE_QUOTA_ITEM_ID"
                   AND "SYS_ALIAS_1"."RESERVE_SCHEME_ITEM_ID" =
                       "GG_RESERVE_SCHEME_ITEM"."RESERVE_SCHEME_ITEM_ID"
                   AND "GG_RESERVE_SCHEME"."RESERVE_SCHEME_ID" =
                       "GG_RESERVE_SCHEME_ITEM"."RESERVE_SCHEME_ID"
                 ORDER BY "GG_RESERVE_SCHEME"."RESERVE_SCHEME_NAME"
DESC
) "INNER_TABLE"
         WHERE "INNER_TABLE"."RELATION_ID" =
               (SELECT
/*+ */

                 MAX("T1"."RELATION_ID")

                  FROM "DG__730"."GG_RESERVE_SCHEME_RELATION" "T1"

                 WHERE "T1"."RESERVE_QUOTA_ITEM_ID" =

                       "INNER_TABLE"."RESERVE_QUOTA_ITEM_ID")
) "from$_subquery$_002"
WHERE "from$_subquery$_002"."OUTER_TABLE_ROWNUM" > 0
   AND "from$_subquery$_002"."OUTER_TABLE_ROWNUM" <= 18

SELECT /*+ */
"from$_subquery$_002"."OUTER_TABLE_ROWNUM"    "OUTER_TABLE_ROWNUM"
  FROM (SELECT /*+ */
         "GG_RESERVE_QUOTA_ITEM"."ORIGINAL_MATERIAL_ID"  "ORIGINAL_MATERIAL_ID",
         ROWNUM                                          "OUTER_TABLE_ROWNUM"
          FROM "DG__730"."GG_RESERVE_QUOTA"           "GG_RESERVE_QUOTA",
               "DG__730"."GG_RESERVE_QUOTA_ITEM"      "GG_RESERVE_QUOTA_ITEM",
               "DG__730"."GG_RESERVE_SCHEME_RELATION" "SYS_ALIAS_1",
               "DG__730"."GG_RESERVE_SCHEME_ITEM"     "GG_RESERVE_SCHEME_ITEM",
               "DG__730"."GG_RESERVE_SCHEME"          "GG_RESERVE_SCHEME"
         WHERE "SYS_ALIAS_1"."RELATION_ID" =
               (SELECT
/*+ */

                 MAX("T1"."RELATION_ID")

                  FROM "DG__730"."GG_RESERVE_SCHEME_RELATION" "T1"

                 WHERE "T1"."RESERVE_QUOTA_ITEM_ID" =

                       "SYS_ALIAS_1"."RESERVE_QUOTA_ITEM_ID")
           AND "GG_RESERVE_QUOTA"."PREPARE_DEPARTMENT_ID" = 1030000003
           AND "GG_RESERVE_QUOTA"."RESERVE_LEVEL" = 1
           AND "GG_RESERVE_QUOTA"."RESERVE_QUOTA_ID" =
               "GG_RESERVE_QUOTA_ITEM"."RESERVE_QUOTA_ID"
           AND "GG_RESERVE_QUOTA_ITEM"."RESERVE_MATERIAL_TYPE" = 37
           AND ("GG_RESERVE_QUOTA_ITEM"."STATUS" = 'disabled' OR
               "GG_RESERVE_QUOTA_ITEM"."STATUS" = 'noScheme' OR
               "GG_RESERVE_QUOTA_ITEM"."STATUS" = 'schemed')
           AND "GG_RESERVE_QUOTA_ITEM"."RESERVE_QUOTA_ITEM_ID" =
               "SYS_ALIAS_1"."RESERVE_QUOTA_ITEM_ID"
           AND "SYS_ALIAS_1"."RESERVE_SCHEME_ITEM_ID" =
               "GG_RESERVE_SCHEME_ITEM"."RESERVE_SCHEME_ITEM_ID"
           AND "GG_RESERVE_SCHEME"."RESERVE_SCHEME_ID" =
               "GG_RESERVE_SCHEME_ITEM"."RESERVE_SCHEME_ID") "from$_subquery$_002"
WHERE "from$_subquery$_002"."OUTER_TABLE_ROWNUM" > 0
   AND "from$_subquery$_002"."OUTER_TABLE_ROWNUM" <= 18

解决方案: 把里面的一个子查询修改,就可以了。
         T.RELATION_ID in (SELECT MAX(T1.RELATION_ID)
                           FROM dg_730.GG_RESERVE_SCHEME_RELATION T1
                          group by RESERVE_QUOTA_ITEM_ID)

抱歉!评论已关闭.