結果まとめ
MySQL
競合ヒント句→ 競合部分は最初のヒントが使用される。その他の部分は有効。
無効ヒント句→ 無効ヒント句よりも前に記載のヒント句は有効、後に記載のヒント句は無効。
Oracle
競合ヒント句→ 競合部分は無視される。その他の部分は有効。
無効ヒント句→ 無効ヒント句よりも前に記載のヒント句は有効、後に記載のヒント句は無効。
PostgreSQL
競合ヒント句→ 競合部分は最後のヒントが使用される。その他の部分は有効。
無効ヒント句→ 無効ヒント句よりも前に記載のヒント句は有効、後に記載のヒント句は無効。
SQL Server
競合ヒント句→ 競合部分は無視される。その他の部分は有効。
無効ヒント句→ SQL文がエラーとなる
(8.0.29)
drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);
drop procedure proc1;
delimiter //
create procedure proc1(in x bigint)
begin
declare i bigint;
set i = 0;
start transaction;
while i < x do
set i = i + 1;
insert into tab1(col1,col2) select ceil(rand()*100000), ceil(rand()*100000);
insert into tab2(col1,col2) select ceil(rand()*100000), ceil(rand()*100000);
end while;
commit;
end
//
delimiter ;
call proc1(1000000);
select count(*) from tab1;
select count(*) from tab2;
select * from tab1 limit 10;
select * from tab2 limit 10;
create index ind1 on tab1(col2);
create index ind2 on tab2(col2);
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;
explain analyze
select /*+ NO_INDEX(t1 ind1) INDEX(t1 ind1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;
explain analyze
select /*+ JOIN_ORDER(t2,t1) NO_INDEX(t1 ind1) INDEX(t1 ind1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;
explain analyze
select /*+ NO_INDEX(t1 ind1) INDEX(t1 ind1) JOIN_ORDER(t1,t2) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;
競合ヒント句は最初のヒントが使用される。その他の部分は有効。
explain analyze
select /*+ JOIN_ORDER(t2,t1) NO_INDEXXX(t1 ind1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;
explain analyze
select /*+ NO_INDEXXX(t1 ind1) JOIN_ORDER(t2,t1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;
無効ヒント句よりも前に記載のヒント句は有効、後に記載のヒント句は無効。
(19c)
drop table tab1 purge;
drop table tab2 purge;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);
declare
begin
for i in 1..1000000 loop
insert into tab1(col1,col2) values(ceil(dbms_random.value()*100000), ceil(dbms_random.value()*100000) );
insert into tab2(col1,col2) values(ceil(dbms_random.value()*100000), ceil(dbms_random.value()*100000) );
end loop;
end;
/
commit;
select count(*) from tab1;
select count(*) from tab2;
select * from tab1 fetch first 10 rows only;
select * from tab2 fetch first 10 rows only;
create index ind1 on tab1(col2);
create index ind2 on tab2(col2);
explain plan for
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );
explain plan for
select /*+ FULL(t1) INDEX(t1 ind1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );
explain plan for
select /*+ LEADING(t1 t2) INDEX(t1 ind1) FULL(t1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );
explain plan for
select /*+ FULL(t1) INDEX(t1 ind1) LEADING(t2 t1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );
競合ヒント句は無視される。その他の部分は有効。
explain plan for
select /*+ LEADING(t1 t2) INDEXXX(t1 ind1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );
explain plan for
select /*+ INDEXXX(t1 ind1) LEADING(t2 t1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );
無効ヒント句よりも前に記載のヒント句は有効、後に記載のヒント句は無効。
(14)
drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);
insert into tab1(col1,col2) select ceil(random()*100000), ceil(random()*100000) from generate_series(1,1000000);
insert into tab2(col1,col2) select ceil(random()*100000), ceil(random()*100000) from generate_series(1,1000000);
select count(*) from tab1;
select count(*) from tab2;
select * from tab1 limit 10;
select * from tab2 limit 10;
create index ind1 on tab1(col2);
create index ind2 on tab2(col2);
set pg_hint_plan.debug_print = 'on';
show pg_hint_plan.debug_print;
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
/*+ IndexScan(t1 ind1) SeqScan(t1) */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
/*+ MergeJoin(t1 t2) SeqScan(t1) IndexScan(t1 ind1) */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
/*+ SeqScan(t1) IndexScan(t1 ind1) MergeJoin(t1 t2) */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
競合ヒント句は最後のヒントが使用される。その他の部分は有効。
/*+ MergeJoin(t1 t2) SeqScannnn(t1) */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
/*+ SeqScannnn(t1) MergeJoin(t1 t2) */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
無効ヒント句よりも前に記載のヒント句は有効、後に記載のヒント句は無効。
(2019)
drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);
set nocount on
declare @i bigint;
set @i = 1;
begin transaction;
while @i <= 1000000
begin
insert into tab1(col1,col2) select ceiling(rand()*100000), ceiling(rand()*100000);
insert into tab2(col1,col2) select ceiling(rand()*100000), ceiling(rand()*100000);
set @i = @i + 1;
end
commit;
select count(*) from tab1;
select count(*) from tab2;
select top(10) * from tab1 ;
select top(10) * from tab2 ;
create index ind1 on tab1(col2);
create index ind2 on tab2(col2);
set showplan_all on
go
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000
;
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000
OPTION ( HASH JOIN , LOOP JOIN );
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000
OPTION ( FORCE ORDER , HASH JOIN , LOOP JOIN );
select count(*)
from tab2 t2 inner join tab1 t1
on t1.col1 = t2.col1
and t1.col2 < 1000
OPTION (HASH JOIN , LOOP JOIN , FORCE ORDER );
競合ヒント句は無視される。その他の部分は有効。
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000
OPTION ( LOOOOOOP JOIN );
無効クエリヒント句はSQL文がエラーとなる