oracle optimization-leading and ordered prompts and materialize prompts

Keywords: Oracle SQL

The following applies to oracle 10.2.0.5 and above

One query is slow, and the original SQL is as follows:

 1 select 
 2  a.*
 3   from (select        
 4          ssi.ID,
 5          'small_station_info' TB,
 6          (select sbi.name
 7             from scene_base_info sbi
 8            where sbi.id = ssi.antenna_selection) as antenna_selection,
 9          ssi.antenna_height,
10          ssi.down_angle,
11          ssi.azimuth_angle,
12          ssi.ITI_ID,
13          sa.longitude,
14          sa.latitude,
15          sa.attach_id
16           from consolidation_demand cd
17           left join demand_test_info dti
18             on cd.id = dti.cd_id
19           left join demand_plan_info dpi
20             on dti.id = dpi.tdl_id
21           left join building_plan_info bpi
22             on dpi.id = bpi.dpi_id
23           left join NEAR_FAR_PLACE_INFO nfpi
24             on bpi.id = nfpi.bpi_id
25           left join SMALL_STATION_INFO ssi
26             on nfpi.id = ssi.nfpi_id
27           left join site_attachment sa
28             on TO_NUMBER(sa.longitude) is not null
29            AND TO_NUMBER(sa.latitude) > 26.074423
30            AND TO_NUMBER(sa.latitude) < 26.077573
31            AND TO_NUMBER(sa.longitude) > 119.191148
32            AND TO_NUMBER(sa.longitude) < 119.197649
33            AND sa.attach_name =
34                substr(ssi.AZIMUTH_ANGLE_PHOTO,
35                       instr(ssi.AZIMUTH_ANGLE_PHOTO, '/', -1) + 1,
36                       length(ssi.AZIMUTH_ANGLE_PHOTO))) a
37  where a.longitude is not null

The tables are not large and the implementation plan is as follows:

12 rows selected.


//Execution Plan
----------------------------------------------------------
Plan hash value: 1917963167

---------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                         |     1 |   253 |   519   (2)| 00:00:07 |
|   1 |  TABLE ACCESS BY INDEX ROWID        | SCENE_BASE_INFO         |     1 |    14 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN                 | SCENE_BASE_INFO_PK      |     1 |       |     0   (0)| 00:00:01 |
|   3 |  VIEW                               |                         |     1 |   253 |   519   (2)| 00:00:07 |
|*  4 |   FILTER                            |                         |       |       |            |       |
|*  5 |    HASH JOIN OUTER                  |                         |     1 |   251 |   519   (2)| 00:00:07 |
|*  6 |     HASH JOIN OUTER                 |                         |    83 |  8134 |   505   (1)| 00:00:07 |
|*  7 |      HASH JOIN OUTER                |                         |    83 |  7304 |   501   (1)| 00:00:07 |
|*  8 |       HASH JOIN OUTER               |                         |    83 |  6391 |   493   (1)| 00:00:06 |
|*  9 |        HASH JOIN OUTER              |                         |    83 |  5478 |   271   (1)| 00:00:04 |
|  10 |         MERGE JOIN CARTESIAN        |                         |    36 |  2052 |    21   (0)| 00:00:01 |
|* 11 |          TABLE ACCESS BY INDEX ROWID| SITE_ATTACHMENT         |     1 |    53 |    16   (0)| 00:00:01 |
|* 12 |           INDEX RANGE SCAN          | IDX_SITE_ATTACHMENT_JWD |     1 |       |    15   (0)| 00:00:01 |
|  13 |          BUFFER SORT                |                         |  6725 | 26900 |     5   (0)| 00:00:01 |
|  14 |           INDEX FAST FULL SCAN      | PK_CONSOLIDATION_DEMAND |  6725 | 26900 |     5   (0)| 00:00:01 |
|  15 |         TABLE ACCESS FULL           | DEMAND_TEST_INFO        | 15459 |   135K|   249   (1)| 00:00:03 |
|  16 |        TABLE ACCESS FULL            | DEMAND_PLAN_INFO        |  8787 | 96657 |   221   (1)| 00:00:03 |
|  17 |       TABLE ACCESS FULL             | BUILDING_PLAN_INFO      |  3244 | 35684 |     8   (0)| 00:00:01 |
|  18 |      TABLE ACCESS FULL              | NEAR_FAR_PLACE_INFO     |   389 |  3890 |     3   (0)| 00:00:01 |
|  19 |     TABLE ACCESS FULL               | SMALL_STATION_INFO      |   594 | 90882 |    13   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SBI"."ID"=:B1)
   4 - filter("SA"."ATTACH_NAME"=SUBSTR("SSI"."AZIMUTH_ANGLE_PHOTO",INSTR("SSI"."AZIMUTH_ANGLE_PHOTO",'
              /',-1)+1,LENGTH("SSI"."AZIMUTH_ANGLE_PHOTO")))
   5 - access("NFPI"."ID"="SSI"."NFPI_ID"(+))
   6 - access("BPI"."ID"="NFPI"."BPI_ID"(+))
   7 - access("DPI"."ID"="BPI"."DPI_ID"(+))
   8 - access("DTI"."ID"="DPI"."TDL_ID"(+))
   9 - access("CD"."ID"="DTI"."CD_ID"(+))
  11 - filter("SA"."LONGITUDE" IS NOT NULL)
  12 - access(TO_NUMBER("LONGITUDE")>119.191148 AND TO_NUMBER("LATITUDE")>26.074423 AND
              TO_NUMBER("LONGITUDE")<119.197649 AND TO_NUMBER("LATITUDE")<26.077573)
       filter(TO_NUMBER("LONGITUDE") IS NOT NULL AND TO_NUMBER("LATITUDE")<26.077573 AND
              TO_NUMBER("LATITUDE")>26.074423)

This execution plan, which looks perfectly normal, should have left join.

The key to the problem, however, is the 10-step MERGE JOIN CARTESIAN.Sort merge joins for Cartesian products, which takes a long time.

Waiting for this result can take tens of seconds, or even longer!
There are several ways to solve this problem:

  1. Re-collect statistics for each table--this has not been experimented with, but it may not work even if you do.In this case, however, it is likely that this is the cause.
  2. Enable leading tips, combined with other tips
  3. Use materialize prompt

Use leading tips

1 select /*+ no_merge(a) no_push_pred(a) */
2  a.*
3   from (select
4         /*+ leading(cd dti dpi bpi ssi) */
5          ...) a
6  where a.longitude is not null
7 /

Execution Plan

12 rows selected.


//Execution Plan
----------------------------------------------------------
Plan hash value: 1844304918

---------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                    | Rows  | Bytes | Cost (%CPU)| Time  |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                         |     1 |   253 |   520   (2)| 00:00:07 |
|   1 |  TABLE ACCESS BY INDEX ROWID  | SCENE_BASE_INFO         |     1 |    14 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN           | SCENE_BASE_INFO_PK      |     1 |       |     0   (0)| 00:00:01 |
|   3 |  VIEW                         |                         |     1 |   253 |   520   (2)| 00:00:07 |
|*  4 |   HASH JOIN                   |                         |     1 |   251 |   520   (2)| 00:00:07 |
|*  5 |    TABLE ACCESS BY INDEX ROWID| SITE_ATTACHMENT         |     1 |    53 |    16   (0)| 00:00:01 |
|*  6 |     INDEX RANGE SCAN          | IDX_SITE_ATTACHMENT_JWD |     1 |       |    15   (0)| 00:00:01 |
|*  7 |    HASH JOIN RIGHT OUTER      |                         | 23606 |  4564K|   503   (2)| 00:00:07 |
|   8 |     TABLE ACCESS FULL         | SMALL_STATION_INFO      |   594 | 90882 |    13   (0)| 00:00:01 |
|*  9 |     HASH JOIN RIGHT OUTER     |                         | 15459 |   679K|   490   (2)| 00:00:06 |
|  10 |      TABLE ACCESS FULL        | NEAR_FAR_PLACE_INFO     |   389 |  3890 |     3   (0)| 00:00:01 |
|* 11 |      HASH JOIN RIGHT OUTER    |                         | 15459 |   528K|   486   (2)| 00:00:06 |
|  12 |       TABLE ACCESS FULL       | BUILDING_PLAN_INFO      |  3244 | 35684 |     8   (0)| 00:00:01 |
|* 13 |       HASH JOIN RIGHT OUTER   |                         | 15459 |   362K|   477   (1)| 00:00:06 |
|  14 |        TABLE ACCESS FULL      | DEMAND_PLAN_INFO        |  8787 | 96657 |   221   (1)| 00:00:03 |
|* 15 |        HASH JOIN OUTER        |                         | 15459 |   196K|   255   (1)| 00:00:04 |
|  16 |         INDEX FAST FULL SCAN  | PK_CONSOLIDATION_DEMAND |  6725 | 26900 |     5   (0)| 00:00:01 |
|  17 |         TABLE ACCESS FULL     | DEMAND_TEST_INFO        | 15459 |   135K|   249   (1)| 00:00:03 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("SBI"."ID"=:B1)
   4 - access("SA"."ATTACH_NAME"=SUBSTR("SSI"."AZIMUTH_ANGLE_PHOTO",INSTR("SSI"."AZIMUTH_ANGLE_PH
              OTO",'/',-1)+1,LENGTH("SSI"."AZIMUTH_ANGLE_PHOTO")))
   5 - filter("SA"."LONGITUDE" IS NOT NULL)
   6 - access(TO_NUMBER("LONGITUDE")>119.191148 AND TO_NUMBER("LATITUDE")>26.074423 AND
              TO_NUMBER("LONGITUDE")<119.197649 AND TO_NUMBER("LATITUDE")<26.077573)
       filter(TO_NUMBER("LONGITUDE") IS NOT NULL AND TO_NUMBER("LATITUDE")<26.077573 AND
              TO_NUMBER("LATITUDE")>26.074423)
   7 - access("NFPI"."ID"="SSI"."NFPI_ID"(+))
   9 - access("BPI"."ID"="NFPI"."BPI_ID"(+))
  11 - access("DPI"."ID"="BPI"."DPI_ID"(+))
  13 - access("DTI"."ID"="DPI"."TDL_ID"(+))
  15 - access("CD"."ID"="DTI"."CD_ID"(+))

There is no Cartesian merge join. Step 4 is also a hash join.
Quick execution, about 0.17 seconds

 

Use materialize prompt

1  WITH A AS
2   (select /*+MATERIALIZE */
3     .....)
4  select a.* from A WHERE a.longitude is not null

Execution Plan

12 rows selected.


//Execution Plan
----------------------------------------------------------
Plan hash value: 3536941173

--------------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                             | 23606 |  5832K|   700   (2)| 00:00:09 |
|   1 |  TEMP TABLE TRANSFORMATION     |                             |       |       |            |       |
|   2 |   LOAD AS SELECT               |                             |       |       |            |       |
|*  3 |    HASH JOIN RIGHT OUTER       |                             | 23606 |  5786K|   520   (2)| 00:00:07 |
|   4 |     TABLE ACCESS BY INDEX ROWID| SITE_ATTACHMENT             |     1 |    53 |    16   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | IDX_SITE_ATTACHMENT_JWD     |     1 |       |    15   (0)| 00:00:01 |
|*  6 |     HASH JOIN RIGHT OUTER      |                             | 23606 |  4564K|   503   (2)| 00:00:07 |
|   7 |      TABLE ACCESS FULL         | SMALL_STATION_INFO          |   594 | 90882 |    13   (0)| 00:00:01 |
|*  8 |      HASH JOIN RIGHT OUTER     |                             | 15459 |   679K|   490   (2)| 00:00:06 |
|   9 |       TABLE ACCESS FULL        | NEAR_FAR_PLACE_INFO         |   389 |  3890 |     3   (0)| 00:00:01 |
|* 10 |       HASH JOIN RIGHT OUTER    |                             | 15459 |   528K|   486   (2)| 00:00:06 |
|  11 |        TABLE ACCESS FULL       | BUILDING_PLAN_INFO          |  3244 | 35684 |     8   (0)| 00:00:01 |
|* 12 |        HASH JOIN RIGHT OUTER   |                             | 15459 |   362K|   477   (1)| 00:00:06 |
|  13 |         TABLE ACCESS FULL      | DEMAND_PLAN_INFO            |  8787 | 96657 |   221   (1)| 00:00:03 |
|* 14 |         HASH JOIN OUTER        |                             | 15459 |   196K|   255   (1)| 00:00:04 |
|  15 |          INDEX FAST FULL SCAN  | PK_CONSOLIDATION_DEMAND     |  6725 | 26900 |     5   (0)| 00:00:01 |
|  16 |          TABLE ACCESS FULL     | DEMAND_TEST_INFO            | 15459 |   135K|   249   (1)| 00:00:03 |
|* 17 |   VIEW                         |                             | 23606 |  5832K|   180   (2)| 00:00:03 |
|  18 |    TABLE ACCESS FULL           | SYS_TEMP_0FD9D68A2_721EF047 | 23606 |  4103K|   180   (2)| 00:00:03 |
--------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("SA"."ATTACH_NAME"(+)=SUBSTR("SSI"."AZIMUTH_ANGLE_PHOTO",INSTR("SSI"."AZIMUTH_ANGLE_PHOT
              O",'/',-1)+1,LENGTH("SSI"."AZIMUTH_ANGLE_PHOTO")))
   5 - access(TO_NUMBER("LONGITUDE"(+))>119.191148 AND TO_NUMBER("LATITUDE"(+))>26.074423 AND
              TO_NUMBER("LONGITUDE"(+))<119.197649 AND TO_NUMBER("LATITUDE"(+))<26.077573)
       filter(TO_NUMBER("LONGITUDE"(+)) IS NOT NULL AND TO_NUMBER("LATITUDE"(+))<26.077573 AND
              TO_NUMBER("LATITUDE"(+))>26.074423)
   6 - access("NFPI"."ID"="SSI"."NFPI_ID"(+))
   8 - access("BPI"."ID"="NFPI"."BPI_ID"(+))
  10 - access("DPI"."ID"="BPI"."DPI_ID"(+))
  12 - access("DTI"."ID"="DPI"."TDL_ID"(+))
  14 - access("CD"."ID"="DTI"."CD_ID"(+))
  17 - filter("A"."LONGITUDE" IS NOT NULL)

Very fast, about 0.19~0.2.
The main reason for the slowness is to generate the gt table SYS_TEMP_0FD9D68A2_721EF047.

 

summary

1. Better to collect statistics first

2. Consider using the leading hint when collecting statistics is invalid, followed by the materialize hint, which can disrupt some self-conscious plans of the oracle optimizer (inadequate optimizers, as oracle has already mentioned, which is why hint comes from)

3.dba is not an easy task to optimize a library and needs to do a lot of work.

Posted by kaisaj on Sat, 15 Jun 2019 14:59:54 -0700