クイズです!
以下の2つのSQLどちらが効率いいでしょう?
(1) |
(2) |
select * from
(
select 1 as tnum, id, dat, d from testUnion1
union all
select 2, id, dat, d from testUnion2
) t
WHERE
dat like '1%' ;
|
select * from
(
select 1 as tnum, id, dat, d from testUnion1 where dat like '1%'
union all
select 2, id, dat, d from testUnion2 where dat like '1%'
) t ;
|
?
?
答え。
どちらも一緒です♪
#これを現場で話したらびっくりされたんで、意外と知られていないのかしら?と思い記事にしました・・・。
?
まぢかよ?!っていわれる人のために、結果を貼り付けておきます。
?
まずOracle10gのトレースから。
?
SQL> select * from
2 (
3 select 1 as tnum, id, dat, d from testUnion1
4 union all
5 select 2, id, dat, d from testUnion2
6 ) t
7 WHERE
8 dat like '1%' ;
6666行が選択されました。
実行計画
----------------------------------------------------------
Plan hash value: 3218570629
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6666 | 338K| 25 (4)| 00:00:01 |
| 1 | VIEW | | 6666 | 338K| 25 (4)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| TESTUNION1 | 3333 | 159K| 13 (8)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| TESTUNION2 | 3333 | 159K| 13 (8)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("DAT" LIKE '1%')
4 - filter("DAT" LIKE '1%')
Note
-----
- dynamic sampling used for this statement
統計
----------------------------------------------------------
0 recursive calls
0 db block gets
523 consistent gets
0 physical reads
0 redo size
202785 bytes sent via SQL*Net to client
5268 bytes received via SQL*Net from client
446 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6666 rows processed
SQL>
SQL> select * from
2 (
3 select 1 as tnum, id, dat, d from testUnion1 where dat like '1%'
4 union all
5 select 2, id, dat, d from testUnion2 where dat like '1%'
6 ) t ;
6666行が選択されました。
実行計画
----------------------------------------------------------
Plan hash value: 3218570629
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6666 | 338K| 25 (4)| 00:00:01 |
| 1 | VIEW | | 6666 | 338K| 25 (4)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| TESTUNION1 | 3333 | 159K| 13 (8)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| TESTUNION2 | 3333 | 159K| 13 (8)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("DAT" LIKE '1%')
4 - filter("DAT" LIKE '1%')
Note
-----
- dynamic sampling used for this statement
統計
----------------------------------------------------------
0 recursive calls
0 db block gets
523 consistent gets
0 physical reads
0 redo size
202785 bytes sent via SQL*Net to client
5268 bytes received via SQL*Net from client
446 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6666 rows processed
こちらはSQLServer2005の実行計画
?
ね、変わらないでしょ?
これを知っているとUNIONした後にまとめてWHERE句書いても
UNIONする前の個々のテーブルに同じWHERE句を何度書いても
一緒だから、記述はUNION後にまとめましょう♪って提案できますね。
?
今日は以上でーす。
#レベル低くてしゅみません。
#リアルであったことの実証を取り合えずBLOGにまとめておいています(ぉぃ