在sql中,使用union替換or,一定會帶來好處,這個是正確的還是錯誤的說法?能否舉個例子
uj5u.com熱心網友回復:
這個錯誤的說法,具體還得看場景,一般來講,or影響SQL陳述句走正確的索引時會考慮用union改寫SQL,但有時也不是這樣的,既然or沒問題,為什么還要用union改寫呢?uj5u.com熱心網友回復:
這個是正確的還是錯誤的說法 這個說法過于教條uj5u.com熱心網友回復:
這是個扯淡的說法。說這話的人的本意是or會導致不走索引,改為union可以走索引。但是實際使用的時候會有多種情況。oracle11g測驗
create table my_big_table as select level a, cast('b' || level as varchar2(8)) b from dual connect by level <= 200000;
create index idx_my_big_table on my_big_table(a, b);下面兩個查詢是等效的,但是都不會走索引
select *
from my_big_table t1
where t1.a = 55654
or t1.b = 'b55654';
select *
from my_big_table t1
where t1.a = 55654
union
select *
from my_big_table t1
where t1.b = 'b55654'
再換一個正確的索引試試
create table my_big_table2 as select level a, cast('b' || level as varchar2(8)) b from dual connect by level <= 200000;
create index idx_my_big_table2_1 on my_big_table2(a);
create index idx_my_big_table2_2 on my_big_table2(b);
又可以看到優化器自作主張給轉成了bitmap。
用hint強制修改執行計劃

從這個執行計劃可以看出確實改成union效率更高,但是優化器會自動幫你做這一步,并且這是根據統計資訊做的智能判斷,無需手動改成union。
再來一組資料奇葩的
create table my_big_table3 as select mod(level, 2) a, cast('b' || level as varchar2(8)) b from dual connect by level <= 200000;
create index idx_my_big_table3_1 on my_big_table3(a);
create index idx_my_big_table3_2 on my_big_table3(b);select * from my_big_table3 t1 where t1.a = 1 or t1.b = 'b1235'; 或者說只要帶上 t1.a = 1 這個條件,你再怎么折騰它都不會走索引。
再用我剛才作業時寫的一個sql舉個例子
select *
from aaa.tab1 t1
where t1.aaaa_date = '20200504'
and t1.day_id = substr('20200504', 7, 2)
and t1.aaaa_no = '01'
and (
(#{levelType} = '1')
or (#{levelType} = '2' and #{saleId} = t1.col1)
or (#{levelType} = '3' and #{saleId} = t1.col2)
)
aaa.tab1表一個磁區雖然有40w資料,但是我本來就是要全表查詢,為什么要改寫?就算我只查幾條資料也不會改寫,因為這張表上沒有索引,如果沒有索引,上面所說的全部都會不成立
uj5u.com熱心網友回復:
單單從代碼看,感覺union 是兩次查詢表,而 or是查詢一次表,只是查詢條件不同
select *
from my_big_table t1
where t1.a = 55654
or t1.b = 'b55654';
select *
from my_big_table t1
where t1.a = 55654
union
select *
from my_big_table t1
where t1.b = 'b55654'
uj5u.com熱心網友回復:
討論效率的時候不能這樣看。你應該看這是 table access full 還是index scan。在特定條件下,后者即使查詢100遍,也可能比前者快。當然這些都需要分情況討論。
uj5u.com熱心網友回復:
你好,你上面的回答說建立這個聯合索引后兩個查詢都沒走索引,但是我在哪里看到過,好像是查詢條件是like前端匹配時會走索引的。如果單單是這樣查詢也不走索引?
from my_big_table t1
where t1.a = 55654
create index idx_my_big_table on my_big_table(a, b);
select *
from my_big_table t1
where t1.a = 55654
union
select *
from my_big_table t1
where t1.b = 'b55654'
uj5u.com熱心網友回復:
@nayi_224,https://blog.csdn.net/z69183787/article/details/86611410 等于號也可以走索引的哦uj5u.com熱心網友回復:
@nayi_224,https://blog.csdn.net/z69183787/article/details/86611410 等于號也可以走索引的哦
不同資料庫之間執行原理不同,別混著看!
oracle中組合索引單查后面的列大概率不走索引。t1.b = 'b55654'已經觸發了一次全表掃描,t1.a = 55654是走索引的,但是從整個查詢來看,不會改善效率。
uj5u.com熱心網友回復:
具體的業務場景下是不同的,不能說union 替代or就一定是好的,這種說法是不對的。轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/13110.html
標籤:開發
