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 的问题很经典。