• where条件中有权限校验的自定义函数优化方法


    下面SQL要跑47秒(SQL已做脱敏处理,最原始SQL要跑几十分钟,添加HINT修正执行计划后跑47秒)
    54316 rows inserted
    Executed in 47.031 seconds

    1. INSERT INTO TMP
    2. SELECT 1,
    3. ORG_ID,
    4. SESSION_ID,
    5. NULL,
    6. NULL,
    7. NULL,
    8. DEPARTMENT_CODE,
    9. NULL,
    10. DEPARTMENT_NAME,
    11. NULL,
    12. SALES_PERSON,
    13. NULL,
    14. PROJECT_NUMBER,
    15. NULL,
    16. NULL,
    17. NULL,
    18. NULL,
    19. NULL,
    20. NULL,
    21. NULL,
    22. ITEM_CATEGORY,
    23. ITEM_CATEGORY_DESC,
    24. NULL,
    25. SO_TYPE,
    26. SO_AREA,
    27. NULL,
    28. NULL,
    29. NULL,
    30. NULL,
    31. NULL,
    32. NULL,
    33. SO_COST,
    34. INTERNAL_SO_COST,
    35. SO_COST_DIFFERENCE,
    36. NULL,
    37. EXPENSE_AMOUNT,
    38. NULL,
    39. NULL,
    40. NULL,
    41. LOT_NUMBER,
    42. SO_HEADER_ID,
    43. NULL,
    44. NULL,
    45. NULL,
    46. NULL,
    47. NULL,
    48. NULL,
    49. NULL,
    50. NULL,
    51. NULL,
    52. NULL,
    53. NULL,
    54. NULL,
    55. NULL,
    56. NULL,
    57. SEGMENT1,
    58. SEGMENT2,
    59. NULL,
    60. NULL,
    61. SEGMENT5,
    62. SEGMENT6,
    63. SEGMENT7,
    64. NULL,
    65. ITEM_TYPE,
    66. CREATION_DATE,
    67. CREATED_BY,
    68. LAST_UPDATED_BY,
    69. LAST_UPDATE_DATE,
    70. LAST_UPDATE_LOGIN,
    71. NULL,
    72. ATTRIBUTE1,
    73. NULL,
    74. NULL,
    75. NULL,
    76. NULL,
    77. NULL,
    78. NULL,
    79. NULL,
    80. NULL,
    81. NULL,
    82. NULL,
    83. NULL,
    84. NULL,
    85. NULL,
    86. ATTRIBUTE15,
    87. NULL,
    88. NULL,
    89. NULL,
    90. NULL,
    91. NULL,
    92. NULL,
    93. NULL,
    94. SO_NUMBER,
    95. SO_LINE_NUM,
    96. NULL,
    97. NULL,
    98. NULL,
    99. NULL,
    100. INV_ITEM_DESCRIPTION,
    101. NULL,
    102. NULL,
    103. NULL,
    104. NULL,
    105. NULL,
    106. NULL,
    107. NULL,
    108. INV_ITEM_NUMBER,
    109. RA_TRX_TYPE_NAME,
    110. NULL
    111. FROM (SELECT /*+ leading(hou) no_merge(hou) full(nh) */
    112. (SELECT HOU.ORGANIZATION_ID
    113. FROM HOU, FSP
    114. WHERE HOU.ORGANIZATION_ID = FSP.ORG_ID
    115. AND FSP.INVENTORY_ORGANIZATION_ID = NH.INV_ORG_ID
    116. AND ROWNUM = 1) ORG_ID,
    117. GCC.SEGMENT2 ATTRIBUTE15,
    118. GCC.SEGMENT6 ITEM_CATEGORY,
    119. (SELECT T.DESCRIPTION
    120. FROM T, B
    121. WHERE B.FLEX_VALUE_ID = T.FLEX_VALUE_ID
    122. AND T.LANGUAGE = 'US'
    123. AND B.FLEX_VALUE_SET_ID = 1014879
    124. AND B.FLEX_VALUE = GCC.SEGMENT6) ITEM_CATEGORY_DESC,
    125. GCC.SEGMENT2 DEPARTMENT_CODE,
    126. (SELECT FFV.DESCRIPTION
    127. FROM FFV
    128. WHERE FFV.FLEX_VALUE_SET_ID = 1014875
    129. AND FFV.FLEX_VALUE = GCC.SEGMENT2) DEPARTMENT_NAME,
    130. GCC.SEGMENT7 PROJECT_NUMBER,
    131. SUM(NVL(NH.UPDATE_AMOUNT, 0)) SO_COST,
    132. DECODE(GCC.SEGMENT5, '0', NULL, SUM(NVL(NH.UPDATE_AMOUNT, 0))) INTERNAL_SO_COST,
    133. GCC.SEGMENT1,
    134. GCC.SEGMENT2,
    135. GCC.SEGMENT5,
    136. GCC.SEGMENT6,
    137. GCC.SEGMENT7,
    138. SYSDATE CREATION_DATE,
    139. FND_GLOBAL.USER_ID CREATED_BY,
    140. FND_GLOBAL.USER_ID LAST_UPDATED_BY,
    141. SYSDATE LAST_UPDATE_DATE,
    142. FND_GLOBAL.LOGIN_ID LAST_UPDATE_LOGIN,
    143. 0 EXPENSE_AMOUNT,
    144. OOH.ORDER_NUMBER SO_NUMBER,
    145. -1 * SUM(NVL(NH.UPDATE_AMOUNT, 0)) SO_COST_DIFFERENCE,
    146. '成本更新' LOT_NUMBER,
    147. (SELECT NVL(B.ATTRIBUTE4, B.ATTRIBUTE2)
    148. FROM T, B, HCA
    149. WHERE B.FLEX_VALUE_ID = T.FLEX_VALUE_ID
    150. AND T.LANGUAGE = 'US'
    151. AND B.FLEX_VALUE_SET_ID = 1014957
    152. AND B.FLEX_VALUE = HCA.ATTRIBUTE11
    153. AND OOL.SOLD_TO_ORG_ID = HCA.CUST_ACCOUNT_ID
    154. AND ROWNUM = 1) SO_AREA,
    155. (SELECT JRSE.RESOURCE_NAME
    156. FROM JRS, JRSE
    157. WHERE JRS.SALESREP_ID = OOH.SALESREP_ID
    158. AND JRS.RESOURCE_ID = JRSE.RESOURCE_ID
    159. AND JRSE.LANGUAGE = 'US'
    160. AND ROWNUM = 1) SALES_PERSON,
    161. NULL SO_TYPE,
    162. (SELECT OTT.DESCRIPTION
    163. FROM OTT
    164. WHERE OOH.ORDER_TYPE_ID = OTT.TRANSACTION_TYPE_ID
    165. AND OTT.LANGUAGE = USERENV('LANG')
    166. AND ROWNUM = 1) RA_TRX_TYPE_NAME,
    167. (SELECT MSIB.DESCRIPTION
    168. FROM MSIB
    169. WHERE OOL.INVENTORY_ITEM_ID = MSIB.INVENTORY_ITEM_ID
    170. AND OOL.SHIP_FROM_ORG_ID = MSIB.ORGANIZATION_ID
    171. AND ROWNUM = 1) INV_ITEM_DESCRIPTION,
    172. OOL.ORDERED_ITEM INV_ITEM_NUMBER,
    173. (SELECT MDEV.ELEMENT_VALUE
    174. FROM MSIB, MDEV
    175. WHERE OOL.INVENTORY_ITEM_ID = MSIB.INVENTORY_ITEM_ID
    176. AND OOL.SHIP_FROM_ORG_ID = MSIB.ORGANIZATION_ID
    177. AND MDEV.ELEMENT_NAME(+) = '商品简称'
    178. AND MDEV.INVENTORY_ITEM_ID(+) = MSIB.INVENTORY_ITEM_ID
    179. AND ROWNUM = 1) ITEM_TYPE,
    180. (SELECT PAF.PER_NAME
    181. FROM PAF, JR
    182. WHERE JR.PERSON_ID = PAF.PERSON_ID
    183. AND NVL(OOH.ATTRIBUTE3, OOH.SALESREP_ID) = JR.SALESREP_ID(+)
    184. AND OOH.ORG_ID = JR.ORG_ID(+)
    185. AND ROWNUM = 1) ATTRIBUTE1,
    186. OOL.LINE_NUMBER || '.' || OOL.SHIPMENT_NUMBER SO_LINE_NUM,
    187. OOH.HEADER_ID SO_HEADER_ID,
    188. null SESSION_ID
    189. FROM NH, GCC, OOL, OOH, FLV, HOU
    190. WHERE NH.UPDATE_CCID = GCC.CODE_COMBINATION_ID
    191. AND OOL.LINE_ID = NH.SO_LINE_ID
    192. AND NH.SO_HEADER_ID = OOL.HEADER_ID
    193. AND OOL.HEADER_ID = OOH.HEADER_ID
    194. AND GCC.SEGMENT2 > '0'
    195. AND GCC.SEGMENT3 >= FLV.MEANING
    196. AND GCC.SEGMENT3 <= FLV.DESCRIPTION
    197. AND DECODE(null, NULL, '-1', GCC.SEGMENT7) =
    198. DECODE(null, NULL, '-1', null)
    199. AND FLV.LOOKUP_TYPE = 'XY_AR_COST_SUBJECT'
    200. AND NVL(FLV.ENABLED_FLAG, 'N') = 'Y'
    201. AND SYSDATE BETWEEN NVL(FLV.START_DATE_ACTIVE, SYSDATE - 1) AND
    202. NVL(FLV.END_DATE_ACTIVE, SYSDATE + 1)
    203. AND GCC.SUMMARY_FLAG = 'N'
    204. AND NH.GL_IF_FLAG = 'OK'
    205. AND HOU.SHORT_CODE = GCC.SEGMENT1
    206. AND HOU.SET_OF_BOOKS_ID = 2022
    207. AND (GCC.SEGMENT1 = null OR null IS NULL)
    208. AND NH.ATTRIBUTE2 >= '2022-01'
    209. AND NH.ATTRIBUTE2 <= '2022-01'
    210. AND (NH.INV_ORG_ID = null OR null IS NULL)
    211. AND OOH.ORG_ID = HOU.ORGANIZATION_ID
    212. AND OOL.ORG_ID = HOU.ORGANIZATION_ID
    213. AND XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y'
    214. AND (OOH.ORG_ID = null OR null IS NULL)
    215. AND (OOL.ORG_ID = null OR null IS NULL)
    216. GROUP BY NH.INV_ORG_ID,
    217. GCC.SEGMENT2,
    218. GCC.SEGMENT6,
    219. GCC.SEGMENT7,
    220. GCC.SEGMENT1,
    221. GCC.SEGMENT5,
    222. OOH.ORDER_NUMBER,
    223. OOL.SOLD_TO_ORG_ID,
    224. OOH.SALESREP_ID,
    225. OOH.ORDER_TYPE_ID,
    226. OOL.INVENTORY_ITEM_ID,
    227. OOL.SHIP_FROM_ORG_ID,
    228. OOL.ORDERED_ITEM,
    229. NVL(OOH.ATTRIBUTE3, OOH.SALESREP_ID),
    230. OOH.ORG_ID,
    231. OOL.LINE_NUMBER || '.' || OOL.SHIPMENT_NUMBER,
    232. OOH.HEADER_ID)

    执行计划比较长就不贴了,这是一条INSERT INTO…SELECT…GROUP BY语句
    一共要插入54316行数据,GROUP BY之前有2685697条数据 

    1. SQL> SELECT /*+ leading(hou) no_merge(hou) full(nh) */
    2. 2 count(*)
    3. 3 FROM NH,
    4. 4 GCC,
    5. 5 OOL,
    6. 6 OOH,
    7. 7 FLV,
    8. 8 HOU
    9. 9 WHERE NH.UPDATE_CCID = GCC.CODE_COMBINATION_ID
    10. 10 AND OOL.LINE_ID = NH.SO_LINE_ID
    11. 11 AND NH.SO_HEADER_ID = OOL.HEADER_ID
    12. 12 AND OOL.HEADER_ID = OOH.HEADER_ID
    13. 13 AND GCC.SEGMENT2 > '0'
    14. 14 AND GCC.SEGMENT3 >= FLV.MEANING
    15. 15 AND GCC.SEGMENT3 <= FLV.DESCRIPTION
    16. 16 AND DECODE(null, NULL, '-1', GCC.SEGMENT7) =
    17. 17 DECODE(null, NULL, '-1', null)
    18. 18 AND FLV.LOOKUP_TYPE = 'XY_AR_COST_SUBJECT'
    19. 19 AND NVL(FLV.ENABLED_FLAG, 'N') = 'Y'
    20. 20 AND SYSDATE BETWEEN
    21. 21 NVL(FLV.START_DATE_ACTIVE, SYSDATE - 1) AND
    22. 22 NVL(FLV.END_DATE_ACTIVE, SYSDATE + 1)
    23. 23 AND GCC.SUMMARY_FLAG = 'N'
    24. 24 AND NH.GL_IF_FLAG = 'OK'
    25. 25 AND HOU.SHORT_CODE = GCC.SEGMENT1
    26. 26 AND HOU.SET_OF_BOOKS_ID = 2022
    27. 27 AND (GCC.SEGMENT1 = null OR null IS NULL)
    28. 28 AND NH.ATTRIBUTE2 >= '2022-01'
    29. 29 AND NH.ATTRIBUTE2 <= '2022-01'
    30. 30 AND (NH.INV_ORG_ID = null OR null IS NULL)
    31. 31 AND OOH.ORG_ID = HOU.ORGANIZATION_ID
    32. 32 AND OOL.ORG_ID = HOU.ORGANIZATION_ID
    33. 33 AND XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y'
    34. 34 AND (OOH.ORG_ID = null OR null IS NULL)
    35. 35 AND (OOL.ORG_ID = null OR null IS NULL)
    36. 36 ;
    37. SQL>
    38. COUNT(*)
    39. ----------
    40. 2685697
    41. Executed in 40.204 seconds

    SQL语句中的where条件部分有个自定义函数,这个自定义函数是用来做权限校验的
    XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y'
    去掉自定义函数看一下速度

    1. SQL> SELECT /*+ leading(hou) no_merge(hou) full(nh) */
    2. 2 count(*)
    3. 3 FROM NH,
    4. 4 GCC,
    5. 5 OOL,
    6. 6 OOH,
    7. 7 FLV,
    8. 8 HOU
    9. 9 WHERE NH.UPDATE_CCID = GCC.CODE_COMBINATION_ID
    10. 10 AND OOL.LINE_ID = NH.SO_LINE_ID
    11. 11 AND NH.SO_HEADER_ID = OOL.HEADER_ID
    12. 12 AND OOL.HEADER_ID = OOH.HEADER_ID
    13. 13 AND GCC.SEGMENT2 > '0'
    14. 14 AND GCC.SEGMENT3 >= FLV.MEANING
    15. 15 AND GCC.SEGMENT3 <= FLV.DESCRIPTION
    16. 16 AND DECODE(null, NULL, '-1', GCC.SEGMENT7) =
    17. 17 DECODE(null, NULL, '-1', null)
    18. 18 AND FLV.LOOKUP_TYPE = 'XY_AR_COST_SUBJECT'
    19. 19 AND NVL(FLV.ENABLED_FLAG, 'N') = 'Y'
    20. 20 AND SYSDATE BETWEEN
    21. 21 NVL(FLV.START_DATE_ACTIVE, SYSDATE - 1) AND
    22. 22 NVL(FLV.END_DATE_ACTIVE, SYSDATE + 1)
    23. 23 AND GCC.SUMMARY_FLAG = 'N'
    24. 24 AND NH.GL_IF_FLAG = 'OK'
    25. 25 AND HOU.SHORT_CODE = GCC.SEGMENT1
    26. 26 AND HOU.SET_OF_BOOKS_ID = 2022
    27. 27 AND (GCC.SEGMENT1 = null OR null IS NULL)
    28. 28 AND NH.ATTRIBUTE2 >= '2022-01'
    29. 29 AND NH.ATTRIBUTE2 <= '2022-01'
    30. 30 AND (NH.INV_ORG_ID = null OR null IS NULL)
    31. 31 AND OOH.ORG_ID = HOU.ORGANIZATION_ID
    32. 32 AND OOL.ORG_ID = HOU.ORGANIZATION_ID
    33. 33 --AND XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y'
    34. 34 AND (OOH.ORG_ID = null OR null IS NULL)
    35. 35 AND (OOL.ORG_ID = null OR null IS NULL)
    36. 36 ;
    37. COUNT(*)
    38. ----------
    39. 2685697
    40. Executed in 10.853 seconds

    不加自定义函数10秒跑完,加了40秒
    因为原始SQL有GROUP BY,而且GROUP BY的列有OOH.ORG_ID,所以可以将
    XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y’放到GROUP BY之后再过滤
    于是原始SQL可以改写为:

    1. INSERT INTO TMP
    2. SELECT 1,
    3. ORG_ID,
    4. SESSION_ID,
    5. NULL,
    6. NULL,
    7. NULL,
    8. DEPARTMENT_CODE,
    9. NULL,
    10. DEPARTMENT_NAME,
    11. NULL,
    12. SALES_PERSON,
    13. NULL,
    14. PROJECT_NUMBER,
    15. NULL,
    16. NULL,
    17. NULL,
    18. NULL,
    19. NULL,
    20. NULL,
    21. NULL,
    22. ITEM_CATEGORY,
    23. ITEM_CATEGORY_DESC,
    24. NULL,
    25. SO_TYPE,
    26. SO_AREA,
    27. NULL,
    28. NULL,
    29. NULL,
    30. NULL,
    31. NULL,
    32. NULL,
    33. SO_COST,
    34. INTERNAL_SO_COST,
    35. SO_COST_DIFFERENCE,
    36. NULL,
    37. EXPENSE_AMOUNT,
    38. NULL,
    39. NULL,
    40. NULL,
    41. LOT_NUMBER,
    42. SO_HEADER_ID,
    43. NULL,
    44. NULL,
    45. NULL,
    46. NULL,
    47. NULL,
    48. NULL,
    49. NULL,
    50. NULL,
    51. NULL,
    52. NULL,
    53. NULL,
    54. NULL,
    55. NULL,
    56. NULL,
    57. SEGMENT1,
    58. SEGMENT2,
    59. NULL,
    60. NULL,
    61. SEGMENT5,
    62. SEGMENT6,
    63. SEGMENT7,
    64. NULL,
    65. ITEM_TYPE,
    66. CREATION_DATE,
    67. CREATED_BY,
    68. LAST_UPDATED_BY,
    69. LAST_UPDATE_DATE,
    70. LAST_UPDATE_LOGIN,
    71. NULL,
    72. ATTRIBUTE1,
    73. NULL,
    74. NULL,
    75. NULL,
    76. NULL,
    77. NULL,
    78. NULL,
    79. NULL,
    80. NULL,
    81. NULL,
    82. NULL,
    83. NULL,
    84. NULL,
    85. NULL,
    86. ATTRIBUTE15,
    87. NULL,
    88. NULL,
    89. NULL,
    90. NULL,
    91. NULL,
    92. NULL,
    93. NULL,
    94. SO_NUMBER,
    95. SO_LINE_NUM,
    96. NULL,
    97. NULL,
    98. NULL,
    99. NULL,
    100. INV_ITEM_DESCRIPTION,
    101. NULL,
    102. NULL,
    103. NULL,
    104. NULL,
    105. NULL,
    106. NULL,
    107. NULL,
    108. INV_ITEM_NUMBER,
    109. RA_TRX_TYPE_NAME,
    110. NULL
    111. FROM (SELECT /*+ leading(hou) no_merge(hou) full(nh) */
    112. (SELECT HOU.ORGANIZATION_ID
    113. FROM HOU, FSP
    114. WHERE HOU.ORGANIZATION_ID = FSP.ORG_ID
    115. AND FSP.INVENTORY_ORGANIZATION_ID = NH.INV_ORG_ID
    116. AND ROWNUM = 1) ORG_ID,
    117. GCC.SEGMENT2 ATTRIBUTE15,
    118. GCC.SEGMENT6 ITEM_CATEGORY,
    119. (SELECT T.DESCRIPTION
    120. FROM T, B
    121. WHERE B.FLEX_VALUE_ID = T.FLEX_VALUE_ID
    122. AND T.LANGUAGE = 'US'
    123. AND B.FLEX_VALUE_SET_ID = 1014879
    124. AND B.FLEX_VALUE = GCC.SEGMENT6) ITEM_CATEGORY_DESC,
    125. GCC.SEGMENT2 DEPARTMENT_CODE,
    126. (SELECT FFV.DESCRIPTION
    127. FROM FFV
    128. WHERE FFV.FLEX_VALUE_SET_ID = 1014875
    129. AND FFV.FLEX_VALUE = GCC.SEGMENT2) DEPARTMENT_NAME,
    130. GCC.SEGMENT7 PROJECT_NUMBER,
    131. SUM(NVL(NH.UPDATE_AMOUNT, 0)) SO_COST,
    132. DECODE(GCC.SEGMENT5, '0', NULL, SUM(NVL(NH.UPDATE_AMOUNT, 0))) INTERNAL_SO_COST,
    133. GCC.SEGMENT1,
    134. GCC.SEGMENT2,
    135. GCC.SEGMENT5,
    136. GCC.SEGMENT6,
    137. GCC.SEGMENT7,
    138. SYSDATE CREATION_DATE,
    139. FND_GLOBAL.USER_ID CREATED_BY,
    140. FND_GLOBAL.USER_ID LAST_UPDATED_BY,
    141. SYSDATE LAST_UPDATE_DATE,
    142. FND_GLOBAL.LOGIN_ID LAST_UPDATE_LOGIN,
    143. 0 EXPENSE_AMOUNT,
    144. OOH.ORDER_NUMBER SO_NUMBER,
    145. -1 * SUM(NVL(NH.UPDATE_AMOUNT, 0)) SO_COST_DIFFERENCE,
    146. '成本更新' LOT_NUMBER,
    147. (SELECT NVL(B.ATTRIBUTE4, B.ATTRIBUTE2)
    148. FROM T, B, HCA
    149. WHERE B.FLEX_VALUE_ID = T.FLEX_VALUE_ID
    150. AND T.LANGUAGE = 'US'
    151. AND B.FLEX_VALUE_SET_ID = 1014957
    152. AND B.FLEX_VALUE = HCA.ATTRIBUTE11
    153. AND OOL.SOLD_TO_ORG_ID = HCA.CUST_ACCOUNT_ID
    154. AND ROWNUM = 1) SO_AREA,
    155. (SELECT JRSE.RESOURCE_NAME
    156. FROM JRS, JRSE
    157. WHERE JRS.SALESREP_ID = OOH.SALESREP_ID
    158. AND JRS.RESOURCE_ID = JRSE.RESOURCE_ID
    159. AND JRSE.LANGUAGE = 'US'
    160. AND ROWNUM = 1) SALES_PERSON,
    161. NULL SO_TYPE,
    162. (SELECT OTT.DESCRIPTION
    163. FROM OTT
    164. WHERE OOH.ORDER_TYPE_ID = OTT.TRANSACTION_TYPE_ID
    165. AND OTT.LANGUAGE = USERENV('LANG')
    166. AND ROWNUM = 1) RA_TRX_TYPE_NAME,
    167. (SELECT MSIB.DESCRIPTION
    168. FROM MSIB
    169. WHERE OOL.INVENTORY_ITEM_ID = MSIB.INVENTORY_ITEM_ID
    170. AND OOL.SHIP_FROM_ORG_ID = MSIB.ORGANIZATION_ID
    171. AND ROWNUM = 1) INV_ITEM_DESCRIPTION,
    172. OOL.ORDERED_ITEM INV_ITEM_NUMBER,
    173. (SELECT MDEV.ELEMENT_VALUE
    174. FROM MSIB, MDEV
    175. WHERE OOL.INVENTORY_ITEM_ID = MSIB.INVENTORY_ITEM_ID
    176. AND OOL.SHIP_FROM_ORG_ID = MSIB.ORGANIZATION_ID
    177. AND MDEV.ELEMENT_NAME(+) = '商品简称'
    178. AND MDEV.INVENTORY_ITEM_ID(+) = MSIB.INVENTORY_ITEM_ID
    179. AND ROWNUM = 1) ITEM_TYPE,
    180. (SELECT PAF.PER_NAME
    181. FROM PAF, JR
    182. WHERE JR.PERSON_ID = PAF.PERSON_ID
    183. AND NVL(OOH.ATTRIBUTE3, OOH.SALESREP_ID) = JR.SALESREP_ID(+)
    184. AND OOH.ORG_ID = JR.ORG_ID(+)
    185. AND ROWNUM = 1) ATTRIBUTE1,
    186. OOL.LINE_NUMBER || '.' || OOL.SHIPMENT_NUMBER SO_LINE_NUM,
    187. OOH.HEADER_ID SO_HEADER_ID,
    188. null SESSION_ID
    189. FROM NH, GCC, OOL, OOH, FLV, HOU
    190. WHERE NH.UPDATE_CCID = GCC.CODE_COMBINATION_ID
    191. AND OOL.LINE_ID = NH.SO_LINE_ID
    192. AND NH.SO_HEADER_ID = OOL.HEADER_ID
    193. AND OOL.HEADER_ID = OOH.HEADER_ID
    194. AND GCC.SEGMENT2 > '0'
    195. AND GCC.SEGMENT3 >= FLV.MEANING
    196. AND GCC.SEGMENT3 <= FLV.DESCRIPTION
    197. AND DECODE(null, NULL, '-1', GCC.SEGMENT7) =
    198. DECODE(null, NULL, '-1', null)
    199. AND FLV.LOOKUP_TYPE = 'XY_AR_COST_SUBJECT'
    200. AND NVL(FLV.ENABLED_FLAG, 'N') = 'Y'
    201. AND SYSDATE BETWEEN NVL(FLV.START_DATE_ACTIVE, SYSDATE - 1) AND
    202. NVL(FLV.END_DATE_ACTIVE, SYSDATE + 1)
    203. AND GCC.SUMMARY_FLAG = 'N'
    204. AND NH.GL_IF_FLAG = 'OK'
    205. AND HOU.SHORT_CODE = GCC.SEGMENT1
    206. AND HOU.SET_OF_BOOKS_ID = 2022
    207. AND (GCC.SEGMENT1 = null OR null IS NULL)
    208. AND NH.ATTRIBUTE2 >= '2022-01'
    209. AND NH.ATTRIBUTE2 <= '2022-01'
    210. AND (NH.INV_ORG_ID = null OR null IS NULL)
    211. AND OOH.ORG_ID = HOU.ORGANIZATION_ID
    212. AND OOL.ORG_ID = HOU.ORGANIZATION_ID
    213. --AND XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y'
    214. AND (OOH.ORG_ID = null OR null IS NULL)
    215. AND (OOL.ORG_ID = null OR null IS NULL)
    216. GROUP BY NH.INV_ORG_ID,
    217. GCC.SEGMENT2,
    218. GCC.SEGMENT6,
    219. GCC.SEGMENT7,
    220. GCC.SEGMENT1,
    221. GCC.SEGMENT5,
    222. OOH.ORDER_NUMBER,
    223. OOL.SOLD_TO_ORG_ID,
    224. OOH.SALESREP_ID,
    225. OOH.ORDER_TYPE_ID,
    226. OOL.INVENTORY_ITEM_ID,
    227. OOL.SHIP_FROM_ORG_ID,
    228. OOL.ORDERED_ITEM,
    229. NVL(OOH.ATTRIBUTE3, OOH.SALESREP_ID),
    230. OOH.ORG_ID,
    231. OOL.LINE_NUMBER || '.' || OOL.SHIPMENT_NUMBER,
    232. OOH.HEADER_ID)
    233. WHERE XY_COM_DEPT_READ.COM_READ(ORG_ID) = 'Y'
    234. 54316 rows inserted
    235. Executed in 17.684 seconds

    改写之后从47秒降低到17秒,有的读者可能会有疑问,这个SQL恰好是GROUP BY的列有OOH.ORG_ID
    如果GROUP BY的列中没有有OOH.ORG_ID,怎么改写呢?其实也很简单,可以这样改写

    1. SQL> SELECT /*+ leading(hou) no_merge(hou) full(nh) */
    2. 2 count(*)
    3. 3 FROM NH,
    4. 4 GCC,
    5. 5 OOL,
    6. 6 OOH,
    7. 7 FLV,
    8. 8 HOU
    9. 9 WHERE NH.UPDATE_CCID = GCC.CODE_COMBINATION_ID
    10. 10 AND OOL.LINE_ID = NH.SO_LINE_ID
    11. 11 AND NH.SO_HEADER_ID = OOL.HEADER_ID
    12. 12 AND OOL.HEADER_ID = OOH.HEADER_ID
    13. 13 AND GCC.SEGMENT2 > '0'
    14. 14 AND GCC.SEGMENT3 >= FLV.MEANING
    15. 15 AND GCC.SEGMENT3 <= FLV.DESCRIPTION
    16. 16 AND DECODE(null, NULL, '-1', GCC.SEGMENT7) =
    17. 17 DECODE(null, NULL, '-1', null)
    18. 18 AND FLV.LOOKUP_TYPE = 'XY_AR_COST_SUBJECT'
    19. 19 AND NVL(FLV.ENABLED_FLAG, 'N') = 'Y'
    20. 20 AND SYSDATE BETWEEN
    21. 21 NVL(FLV.START_DATE_ACTIVE, SYSDATE - 1) AND
    22. 22 NVL(FLV.END_DATE_ACTIVE, SYSDATE + 1)
    23. 23 AND GCC.SUMMARY_FLAG = 'N'
    24. 24 AND NH.GL_IF_FLAG = 'OK'
    25. 25 AND HOU.SHORT_CODE = GCC.SEGMENT1
    26. 26 AND HOU.SET_OF_BOOKS_ID = 2022
    27. 27 AND (GCC.SEGMENT1 = null OR null IS NULL)
    28. 28 AND NH.ATTRIBUTE2 >= '2022-01'
    29. 29 AND NH.ATTRIBUTE2 <= '2022-01'
    30. 30 AND (NH.INV_ORG_ID = null OR null IS NULL)
    31. 31 AND OOH.ORG_ID = HOU.ORGANIZATION_ID
    32. 32 AND OOL.ORG_ID = HOU.ORGANIZATION_ID
    33. 33 --AND XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y'
    34. 34 AND EXISTS (SELECT /*+ NO_UNNEST */ NULL FROM DUAL WHERE XY_COM_DEPT_READ.COM_READ(OOH.ORG_ID) = 'Y')
    35. 35 AND (OOH.ORG_ID = null OR null IS NULL)
    36. 36 AND (OOL.ORG_ID = null OR null IS NULL)
    37. 37 ;
    38. COUNT(*)
    39. ----------
    40. 2685697
    41. Executed in 15.281 seconds

    改写为EXISTS(SELECT /*+ NO_UNNEST */)让其走FILTER,因为FILTER有去重功能,所以走FILTER也会减少函数被调用的次数
    总结:最优的方法应该是将自定义函数中的SQL提取出来,改写为表连接,但是有时候自定义函数特别复杂,改写为表连接相比减少函数被调用次数性能提升也没有特别大的提升,所以就不必要去折腾

  • 相关阅读:
    江苏建筑模板厂家-建筑模板批发供应商
    基于 Scriptable 从零开始美化iOS桌面(集合篇)
    Linux 同步管理(上)
    黑马程序员C++类和对象【5】 —— 运算符重载(蓝桥杯必备知识)万字超详解
    批量上传图片
    Java 复习笔记 - 集合进阶篇:数据结构
    1.Zookeeper理论基础
    A*(A星,Astar)路径规划算法
    STM32串口通信
    学习笔记-java代码审计-表达式注入
  • 原文地址:https://blog.csdn.net/robinson1988/article/details/127423530