关于union all 的优化

1:还是先看看这个差性能的sql执行计划,本来此类sql的执行计划凭经验就知道有多少集合就有多少次对表的扫描。

SQL> explain plan for
  2  select count(*) from playinfo t where tableid=1 and shoeid=11493 and betresult=1 
  3  union all
  4  select count(*) from playinfo t where tableid=1 and shoeid=11493 and betresult=2 
  5  union all
  6  select count(*) from playinfo t where tableid=1 and shoeid=11493 and betresult=3
  7  union all
  8  select count(*) from playinfo t where tableid=1 and shoeid=11494 and betresult=1 
  9  union all
 10  select count(*) from playinfo t where tableid=1 and shoeid=11494 and betresult=2 
 11  union all
 12  select count(*) from playinfo t where tableid=1 and shoeid=11494 and betresult=3
 13  union all
 14  select count(*) from playinfo t where tableid=1 and shoeid=11495 and betresult=1 
 15  union all
 16  select count(*) from playinfo t where tableid=1 and shoeid=11495 and betresult=2 
 17  union all
 18  select count(*) from playinfo t where tableid=1 and shoeid=11495 and betresult=3 
 19  union all
 20  select count(*) from playinfo t where tableid=1 and shoeid=11496 and betresult=1 
 21  union all
 22  select count(*) from playinfo t where tableid=1 and shoeid=11496 and betresult=2 
 23  union all
 24  select count(*) from playinfo t where tableid=1 and shoeid=11496 and betresult=3
 25  union all
 26  select count(*) from playinfo t where tableid=1 and shoeid=11497 and betresult=1 
 27  union all
 28  select count(*) from playinfo t where tableid=1 and shoeid=11497 and betresult=2 
 29  union all
  30  select count(*) from playinfo t where tableid=1 and shoeid=11497 and betresult=3
 31  union all
 32  select count(*) from playinfo t where tableid=1 and shoeid=11498 and betresult=1 
 33  union all
 34  select count(*) from playinfo t where tableid=1 and shoeid=11498 and betresult=2 
 35  union all
 36  select count(*) from playinfo t where tableid=1 and shoeid=11498 and betresult=3
 37  union all
 38  select count(*) from playinfo t where tableid=1 and shoeid=11499 and betresult=1 
 39  union all
 40  select count(*) from playinfo t where tableid=1 and shoeid=11499 and betresult=2 
 41  union all
 42  select count(*) from playinfo t where tableid=1 and shoeid=11499 and betresult=3
 43  union all
 44  select count(*) from playinfo t where tableid=1 and shoeid=11500 and betresult=1 
 45  union all
 46  select count(*) from playinfo t where tableid=1 and shoeid=11500 and betresult=2 
 47  union all
 48  select count(*) from playinfo t where tableid=1 and shoeid=11500 and betresult=3
 49  union all
 50  select count(*) from playinfo t where tableid=1 and shoeid=11501 and betresult=1 
 51  union all
 52  select count(*) from playinfo t where tableid=1 and shoeid=11501 and betresult=2 
 53  union all
 54  select count(*) from playinfo t where tableid=1 and shoeid=11501 and betresult=3 
 55  union all
 56  select count(*) from playinfo t where tableid=1 and shoeid=11502 and betresult=1 
 57  union all
select count(*) from playinfo t where tableid=1 and shoeid=11502 and betresult=2 
 59  union all
 60  select count(*) from playinfo t where tableid=1 and shoeid=11502 and betresult=3
 61  union all
 62  select count(*) from playinfo t where tableid=1 and shoeid=11503 and betresult=1 
 63  union all
 64  select count(*) from playinfo t where tableid=1 and shoeid=11503 and betresult=2 
 65  union all
select count(*) from playinfo t where tableid=1 and shoeid=11503 and betresult=3
 67  union all
 68  select count(*) from playinfo t where tableid=1 and shoeid=11504 and betresult=1 
 69  union all
 70  select count(*) from playinfo t where tableid=1 and shoeid=11504 and betresult=2 
 71  union all
 72  select count(*) from playinfo t where tableid=1 and shoeid=11504 and betresult=3
 73  union all
 74  select count(*) from playinfo t where tableid=1 and shoeid=11505 and betresult=1 
 75  union all
 76  select count(*) from playinfo t where tableid=1 and shoeid=11505 and betresult=2 
 77  union all
 78  select count(*) from playinfo t where tableid=1 and shoeid=11505 and betresult=3
 79  union all
 80  select count(*) from playinfo t where tableid=1 and shoeid=11506 and betresult=1 
 81  union all
 82  select count(*) from playinfo t where tableid=1 and shoeid=11506 and betresult=2 
 83  union all
 84  select count(*) from playinfo t where tableid=1 and shoeid=11506 and betresult=3
 85  union all
 86  select count(*) from playinfo t where tableid=1 and shoeid=11507 and betresult=1 
 87  union all
 88  select count(*) from playinfo t where tableid=1 and shoeid=11507 and betresult=2 
 89  union all
 90  select count(*) from playinfo t where tableid=1 and shoeid=11507 and betresult=3
 91  union all
 92  select count(*) from playinfo t where tableid=1 and shoeid=11508 and betresult=1 
 93  union all
 94  select count(*) from playinfo t where tableid=1 and shoeid=11508 and betresult=2 
 95  union all
 96  select count(*) from playinfo t where tableid=1 and shoeid=11508 and betresult=3
 97  /

Explained.
SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3417941786

--------------------------------------------------------------------------------
| Id  | Operation           | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |          |    48 |   528 |   241  (98)| 00:00:03 |
|   1 |  UNION-ALL          |          |       |       |            |          |
|   2 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|*  3 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|   4 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|*  5 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|   6 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|*  7 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|   8 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|*  9 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  10 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 11 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  12 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 13 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  14 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 15 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  16 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 17 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  18 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 19 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  20 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 21 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  22 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 23 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  24 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 25 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  26 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 27 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  28 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 29 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  30 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
* 31 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  32 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 33 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  34 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 35 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  36 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 37 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  38 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 39 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  40 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 41 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  42 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 43 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  44 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 45 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  46 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 47 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  48 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 49 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  50 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 51 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  52 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 53 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  54 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 55 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  56 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 57 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  58 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 59 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  60 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 61 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  62 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 63 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  64 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 65 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  66 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 67 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  68 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 69 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  70 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 71 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  72 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 73 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  74 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 75 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  76 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 77 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  78 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 79 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  80 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 81 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  82 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 83 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  84 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 85 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  86 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 87 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  88 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 89 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  90 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 91 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
|  92 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 93 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  94 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 95 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
|  96 |   SORT AGGREGATE    |          |     1 |    11 |            |          |
|* 97 |    TABLE ACCESS FULL| PLAYINFO |    18 |   198 |     5   (0)| 00:00:01 |
--------------------------------------------------------------------------------

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

   3 - filter("SHOEID"=11493 AND "BETRESULT"=1 AND "TABLEID"=1)
   5 - filter("SHOEID"=11493 AND "BETRESULT"=2 AND "TABLEID"=1)
   7 - filter("SHOEID"=11493 AND "BETRESULT"=3 AND "TABLEID"=1)
      9 - filter("SHOEID"=11494 AND "BETRESULT"=1 AND "TABLEID"=1)
  11 - filter("SHOEID"=11494 AND "BETRESULT"=2 AND "TABLEID"=1)
  13 - filter("SHOEID"=11494 AND "BETRESULT"=3 AND "TABLEID"=1)
  15 - filter("SHOEID"=11495 AND "BETRESULT"=1 AND "TABLEID"=1)
  17 - filter("SHOEID"=11495 AND "BETRESULT"=2 AND "TABLEID"=1)
  19 - filter("SHOEID"=11495 AND "BETRESULT"=3 AND "TABLEID"=1)
  21 - filter("SHOEID"=11496 AND "BETRESULT"=1 AND "TABLEID"=1)
  23 - filter("SHOEID"=11496 AND "BETRESULT"=2 AND "TABLEID"=1)
  25 - filter("SHOEID"=11496 AND "BETRESULT"=3 AND "TABLEID"=1)
  27 - filter("SHOEID"=11497 AND "BETRESULT"=1 AND "TABLEID"=1)
  29 - filter("SHOEID"=11497 AND "BETRESULT"=2 AND "TABLEID"=1)
  31 - filter("SHOEID"=11497 AND "BETRESULT"=3 AND "TABLEID"=1)
  33 - filter("SHOEID"=11498 AND "BETRESULT"=1 AND "TABLEID"=1)
  35 - filter("SHOEID"=11498 AND "BETRESULT"=2 AND "TABLEID"=1)
  37 - filter("SHOEID"=11498 AND "BETRESULT"=3 AND "TABLEID"=1)
  39 - filter("SHOEID"=11499 AND "BETRESULT"=1 AND "TABLEID"=1)
  41 - filter("SHOEID"=11499 AND "BETRESULT"=2 AND "TABLEID"=1)
  43 - filter("SHOEID"=11499 AND "BETRESULT"=3 AND "TABLEID"=1)
  45 - filter("SHOEID"=11500 AND "BETRESULT"=1 AND "TABLEID"=1)
  47 - filter("SHOEID"=11500 AND "BETRESULT"=2 AND "TABLEID"=1)
  49 - filter("SHOEID"=11500 AND "BETRESULT"=3 AND "TABLEID"=1)
  51 - filter("SHOEID"=11501 AND "BETRESULT"=1 AND "TABLEID"=1)
  53 - filter("SHOEID"=11501 AND "BETRESULT"=2 AND "TABLEID"=1)
  55 - filter("SHOEID"=11501 AND "BETRESULT"=3 AND "TABLEID"=1)
  57 - filter("SHOEID"=11502 AND "BETRESULT"=1 AND "TABLEID"=1)
  59 - filter("SHOEID"=11502 AND "BETRESULT"=2 AND "TABLEID"=1)
  61 - filter("SHOEID"=11502 AND "BETRESULT"=3 AND "TABLEID"=1)
  63 - filter("SHOEID"=11503 AND "BETRESULT"=1 AND "TABLEID"=1)
  65 - filter("SHOEID"=11503 AND "BETRESULT"=2 AND "TABLEID"=1)
  67 - filter("SHOEID"=11503 AND "BETRESULT"=3 AND "TABLEID"=1)
  69 - filter("SHOEID"=11504 AND "BETRESULT"=1 AND "TABLEID"=1)
  71 - filter("SHOEID"=11504 AND "BETRESULT"=2 AND "TABLEID"=1)
  73 - filter("SHOEID"=11504 AND "BETRESULT"=3 AND "TABLEID"=1)
  75 - filter("SHOEID"=11505 AND "BETRESULT"=1 AND "TABLEID"=1)
  77 - filter("SHOEID"=11505 AND "BETRESULT"=2 AND "TABLEID"=1)
  79 - filter("SHOEID"=11505 AND "BETRESULT"=3 AND "TABLEID"=1)
  81 - filter("SHOEID"=11506 AND "BETRESULT"=1 AND "TABLEID"=1)
  83 - filter("SHOEID"=11506 AND "BETRESULT"=2 AND "TABLEID"=1)
  85 - filter("SHOEID"=11506 AND "BETRESULT"=3 AND "TABLEID"=1)
  87 - filter("SHOEID"=11507 AND "BETRESULT"=1 AND "TABLEID"=1)
  89 - filter("SHOEID"=11507 AND "BETRESULT"=2 AND "TABLEID"=1)
  91 - filter("SHOEID"=11507 AND "BETRESULT"=3 AND "TABLEID"=1)
  93 - filter("SHOEID"=11508 AND "BETRESULT"=1 AND "TABLEID"=1)
  95 - filter("SHOEID"=11508 AND "BETRESULT"=2 AND "TABLEID"=1)
  97 - filter("SHOEID"=11508 AND "BETRESULT"=3 AND "TABLEID"=1)

156 rows selected.


--分析上述sql。发现都是同一张表。并且谓词条件是范围的。那么直接改为简单的分组语句就可以达到同样的效果
--改写sql如下

SQL> explain plan for
  2  select shoeid,BETRESULT,count(*) from playinfo where shoeid between 11493 and 11508 and BETRESULT  between 1 and 3 and  tableid=1 group by shoeid,BETRESULT order by shoeid ;

Explained.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 184645364

-------------------------------------------------------------------------------
| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |    34 |   374 |     6  (17)| 00:00:01 |
|   1 |  SORT GROUP BY     |          |    34 |   374 |     6  (17)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| PLAYINFO |   842 |  9262 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------

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

   2 - filter("SHOEID">=11493 AND "SHOEID"<=11508 AND "BETRESULT">=1
              AND "BETRESULT"<=3 AND "TABLEID"=1)

15 rows selected.


--扫描次数只有一次。看到谓词条件为3个字段,但是出现了全表扫描。如果加个复合index效果更好

SQL> create index index_multi on PLAYINFO(SHOEID,BETRESULT,TABLEID);

Index created.

SQL> begin
  2  dbms_stats.gather_table_stats(ownname=>'TEST',tabname=>'PLAYINFO',
  3  cascade => true,
  4  estimate_percent => null,degree =>2,
  5  method_opt => 'for all columns size 1'
  6  );
  7  end;
  8  /

PL/SQL procedure successfully completed.


SQL> explain plan for
  2  select shoeid,BETRESULT,count(*) from playinfo where shoeid between 11493 and 11508 and BETRESULT  between 1 and 3 and  tableid=1 group by shoeid,BETRESULT order by shoeid ;

Explained.

SQL>  select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1317533731

-------------------------------------------------------------------------------------
| Id  | Operation             | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |             |    34 |   374 |     3  (34)| 00:00:01 |
|   1 |  SORT GROUP BY        |             |    34 |   374 |     3  (34)| 00:00:01 |
|*  2 |   INDEX FAST FULL SCAN| INDEX_MULTI |   842 |  9262 |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   2 - filter("SHOEID">=11493 AND "SHOEID"<=11508 AND "BETRESULT">=1 AND
              "BETRESULT"<=3 AND "TABLEID"=1)

15 rows selected.

 

--总结:

对于此类大量的union all 集合,造成重复扫描的工作。可以考虑with as 语句。

如果按照业务逻辑来直接写sql,出现这种sql的话。就要考虑换个方式来进行改写。

此类sql 的问题很经典。
 

你可能感兴趣的:(sql)