一般情況下,在兩表連線時,表記錄條數較少的會被作為驅動表,根據每乙個驅動表的記錄,去匹配被驅動表的所有滿足條件的資料。如果是這種掃瞄方式,那麼這裡問題就來了,,為什麼說條數較少的表作為驅動表,效率就一定高呢?
下面實驗:
先實驗一般情況:
建表create table a (id number,name char(8));
create table b (id number,name char(8));
插入資料
/*begin
for i in 1..10 loop
insert into a values(i,to_char(round(dbms_random.value,8)*100000000));
end loop;
commit;
end;
*//*begin
for i in 1..1000 loop
insert into b values(i,to_char(round(dbms_random.value,8)*100000000));
end loop;
commit;
end;
*/--select count(1) from a;
--select count(1) from b;
--收集
begin
dbms_stats.gather_table_stats(ownname => 'scott',tabname => 'a');
end;
--begin
dbms_stats.gather_table_stats(ownname => 'scott',tabname => 'b');
end;
---測試巢狀效率,去sqlplus開 traceonly
select * from a,b where a.id=b.id; -- cost 6 hash join
select /*+leading(a) use_nl(a b)*/ * from scott.a a,scott.b b where a.id=b.id; --cost 18 bytes 250 68 consiste
select /*+ leading(b) use_nl(b a)*/ * from scott.a a,scott.b b where a.id=b.id; -- cost 1360 ,6000consistent
select * from user_tables a where a.table_name in ('a','b'); -- 檢視記錄數和表塊數的比例,思考
-- 在塊數小於記錄數的情況下,上述成立,如果遇到大記錄的情況下呢
--構造b表 大記錄,a表維持不變
create table c (id number,
name1 char(8)
);create table d (id number,
name1 char(2000),
name2 char(2000),
name3 char(2000)
);/*
begin
for i in 1..10 loop
insert into c values(i,
to_char(round(dbms_random.value,8)*100000000));
end loop;
commit;
end;
*//*begin
begin
for i in 1..1000 loop
insert into d values(i,
to_char(round(dbms_random.value,8)*100000000),
to_char(round(dbms_random.value,8)*100000000),
to_char(round(dbms_random.value,8)*100000000)
);end loop;
commit;
end;
*/begin
dbms_stats.gather_table_stats(ownname => 'scott',tabname => 'c');
end;
begin
dbms_stats.gather_table_stats(ownname => 'scott',tabname => 'd');
end;
select * from user_tables a where a.table_name in ('c','d');
-- c表 10條記錄,5個block d表1000條記錄,,1000個block
-- 再次測試巢狀迴圈,bingo
select * from scott.c ,scott.d where c.id=d.id;
select /*+ leading(c) use_nl(c d)*/ * from scott.c c,scott.d d where c.id=d.id; --cost 2715 bytes 390k 10047 consiste
select /*+ leading(d) use_nl(d c)*/ * from scott.c c,scott.d d where c.id=d.id; -- cost 12747 ,52060 consistent
-- 由於io對cost計算影響比較大,所有這裡通過改變表的行大小來改變塊與資料行數的比例
--oracle在這裡使用了d表作為驅動表,看來是嚴格按照cost計算方式來選擇的。
-- 如果單純認為 資料量小的表就會作為驅動表,那就錯了。
MySQL 驅動表和被驅動表
先了解在join連線時哪個表是驅動表,哪個表是被驅動表 1.當使用left join時,左表是驅動表,右表是被驅動表 2.當使用right join時,右表時驅動表,左表是驅動表 3.當使用join時,mysql會選擇資料量比較小的表作為驅動表,大表作為被驅動表 join查詢如何選擇驅動表與被驅動表...
mysql 大表 驅動 MySQL小表驅動大表
在了解之前要先了解對應語法 in 與 exist。in後的括號的表示式結果要求先輸出一列字段。與之前的搜尋字段匹配,匹配到相同則返回對應行。mysql的執行順序是先執行子查詢,然後執行主查詢,用子查詢的結果按條匹配主查詢。exist後的括號裡則無輸出要求,exist判斷後面的結果集中有沒有行,有行則...
小表驅動大表
類似迴圈巢狀。for int i 5 如果小的迴圈在外層,對於資料庫連線來說就只連線5次,進行5000次操作,如果1000在外,則需要進行1000次資料庫連線,從而浪費資源,增加消耗。這就是為什麼要小表驅動大表。在tb dept bigdata表中插入100條資料,在tb emp bigdata表中...