3 回答

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超3個(gè)贊
您閱讀的文章使用了一個(gè)錯(cuò)誤的例子,或者您誤解了他們的觀點(diǎn)。
select username from users where company = 'bbc' or company = 'itv';
這等效于:
select username from users where company IN ('bbc', 'itv');
MySQL可以company為此查詢使用索引。無需執(zhí)行任何UNION。
更棘手的情況是您的OR條件涉及兩個(gè)不同的列。
select username from users where company = 'bbc' or city = 'London';
假設(shè)在上有一個(gè)索引,在上company有一個(gè)單獨(dú)的索引city。鑒于MySQL通常在給定查詢中每個(gè)表只使用一個(gè)索引,應(yīng)該使用哪個(gè)索引?如果它使用on上的索引company,則仍必須進(jìn)行表掃描以查找city倫敦所在的行。如果使用on上的索引city,則必須對(duì)companybbc 所在的行進(jìn)行表掃描。
該UNION解決方案是對(duì)于這種類型的箱子。
select username from users where company = 'bbc'
union
select username from users where city = 'London';
現(xiàn)在,每個(gè)子查詢都可以使用索引進(jìn)行搜索,并且子查詢的結(jié)果由組合UNION。
一位匿名用戶對(duì)我的回答提出了修改建議,但主持人拒絕了該修改。它應(yīng)該是評(píng)論,而不是編輯。提議的編輯聲稱,UNION必須對(duì)結(jié)果集進(jìn)行排序以消除重復(fù)的行。這會(huì)使查詢運(yùn)行速度變慢,因此索引優(yōu)化是一項(xiàng)艱巨的任務(wù)。
我的回答是,索引有助于在UNION發(fā)生之前將結(jié)果集減少為少量的行。實(shí)際上,UNION確實(shí)消除了重復(fù)項(xiàng),但是這樣做只需要對(duì)小的結(jié)果集進(jìn)行排序。在某些情況下,WHERE子句與表的大部分匹配,并且在UNION期間進(jìn)行排序與進(jìn)行表掃描一樣昂貴。但是,通過索引搜索減少結(jié)果集的情況更為常見,因此排序的成本要比表掃描的成本低得多。
差異取決于表中的數(shù)據(jù)以及要搜索的術(shù)語。確定給定查詢的最佳解決方案的唯一方法是嘗試在MySQL查詢探查器中使用這兩種方法并比較它們的性能。

TA貢獻(xiàn)1900條經(jīng)驗(yàn) 獲得超5個(gè)贊
這些不是相同的查詢。
我對(duì)MySQL沒有太多的經(jīng)驗(yàn),所以我不確定查詢優(yōu)化器會(huì)做什么或不做什么,但是這是我一般背景下的想法(主要是ms sql server)。
通常,查詢分析器可以采用上述兩個(gè)查詢,并根據(jù)它們制定完全相同的計(jì)劃(如果它們相同),所以沒關(guān)系。我懷疑這些查詢之間沒有性能差異(等效)
select distinct username from users where company = ‘bbc’ or company = ‘itv’;
和
select username from users where company = ‘bbc’
union
select username from users where company = ‘itv’;
現(xiàn)在的問題是,以下查詢之間是否會(huì)有區(qū)別,而我實(shí)際上并不知道這些區(qū)別,但是我懷疑優(yōu)化程序會(huì)使它更像第一個(gè)查詢
select username from users where company = ‘bbc’ or company = ‘itv’;
和
select username from users where company = ‘bbc’
union all
select username from users where company = ‘itv’;

TA貢獻(xiàn)1853條經(jīng)驗(yàn) 獲得超9個(gè)贊
這取決于優(yōu)化器根據(jù)數(shù)據(jù),索引,軟件版本等的大小來完成的工作。
我猜想使用OR會(huì)給優(yōu)化器提供更高的效率,因?yàn)樗袃?nèi)容都在一個(gè)邏輯語句中。
同樣,UNION也有一些開銷,因?yàn)樗鼊?chuàng)建了一個(gè)重置集(沒有重復(fù)項(xiàng))。在UNION每個(gè)語句應(yīng)該執(zhí)行很快,如果公司被索引...不知道它會(huì)真的做雙倍的工作。
底線
除非您確實(shí)有迫切需要從查詢中擠出每一點(diǎn)速度,否則最好采用能最好地傳達(dá)您意圖的表格。
更新資料
我也想提到IN。我相信以下查詢將比OR提供更好的性能(這也是我更喜歡的形式):
select username from users where company in ('bbc', 'itv');
添加回答
舉報(bào)