<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          union和union all的性能差別居然這么大??!

          共 1477字,需瀏覽 3分鐘

           ·

          2021-12-23 18:22

          最近做個(gè)項(xiàng)目,要把我們系統(tǒng)中的用戶數(shù)據(jù),按照別人系統(tǒng)的格式要求生成數(shù)據(jù)文本,導(dǎo)入到別的系統(tǒng)中。

          我們系統(tǒng)的用戶數(shù)據(jù)主要存放在兩個(gè)表中,用戶信息表(user)和用戶附加信息表(extend)。user表中主要是用戶id,用戶昵稱、用戶名等信息,extend表中主要是手機(jī)號(hào)、身份證、核心客戶號(hào)碼等信息。每個(gè)表的主鍵都是用戶id(字段名為uid),分別有1.6億數(shù)據(jù),關(guān)聯(lián)查詢導(dǎo)出即可。

          查詢要求

          • 核心客戶號(hào)(cusnum)有效的用戶,即不為空、不為零。

          • 核心客戶號(hào)(cusnum)為空,身份三要素(姓名name、證件類型certType、證件號(hào)碼certNum)有效的情況。

          SQL語句

          查詢SQL非常簡(jiǎn)單,分別將滿足條件的數(shù)據(jù)查出來做個(gè)合并,導(dǎo)出至指定文件即可。

          // 核心客戶號(hào)有效
          select ...
          from user u inner join extend e
          on u.uid=e.uid
          where e.cusnum IS NOT NULL and e.cusnum != '' and e.cusnum != 0
          union
          // 核心客戶號(hào)為空,身份三要素有效
          select ...
          from user u inner join extend e
          on u.uid=e.uid
          where (e.cusnum IS NULL or e.cusnum = '' or e.cusnum = 0)
          and (e.name IS NOT NULL and e.name != '')
          and (e.certType IS NOT NULL and e.certType != '')
          and (e.certNum IS NOT NULL and e.certNum != '')
          into outfile '/xxxxx/xxxx.txt'

          但是使用這個(gè)SQL,導(dǎo)出全部1.6億的數(shù)據(jù)竟然用了14個(gè)小時(shí)?。。?/span>

          這個(gè)時(shí)間已經(jīng)遠(yuǎn)遠(yuǎn)超過了投產(chǎn)的時(shí)間窗口,1.6億數(shù)據(jù)雖然會(huì)慢,但沒道理會(huì)這么慢呀。

          把兩個(gè)SQL分別執(zhí)行導(dǎo)出,每個(gè)語句執(zhí)行了不到20分鐘就完成了,但是使用union在一起竟然會(huì)變得這么慢。

          union機(jī)制

          隨后,我就查了查mysql的union機(jī)制,才知道union不僅對(duì)多個(gè)sql的查詢結(jié)果做了合并,還在合并的基礎(chǔ)上做了默認(rèn)排序,同時(shí)還去除了重復(fù)行。1.6億的數(shù)據(jù)進(jìn)行排序、歸并,想想就頭疼。

          如果不對(duì)查詢結(jié)果進(jìn)行排序、去重的話,可以使用union all。

          union all 只是簡(jiǎn)單的將兩個(gè)結(jié)果合并后就返回。如果返回的兩個(gè)結(jié)果集中有重復(fù)的數(shù)據(jù),那么返回的結(jié)果集就會(huì)包含重復(fù)的數(shù)據(jù)了。

          在我們的這個(gè)場(chǎng)景中,第一個(gè)語句的條件是cusnum有效,第二個(gè)語句的查詢條件是cusnum無效,因此不會(huì)有重復(fù)的數(shù)據(jù)。而且我們只要把數(shù)據(jù)全部導(dǎo)出即可,不關(guān)注數(shù)據(jù)的順序,因此我們可以用union all來替換union。

          修改后再次執(zhí)行,這次只花費(fèi)不到30分鐘就把數(shù)據(jù)導(dǎo)出了,效率提升了28倍。如果數(shù)據(jù)量更大的話,這個(gè)效率提升會(huì)更明顯。

          總結(jié)

          UNION ALL 要比UNION快很多,所以,如果可以確認(rèn)合并的兩個(gè)結(jié)果集中不包含重復(fù)數(shù)據(jù)且不需要排序時(shí)的話,那么就使用UNION ALL。



          瀏覽 45
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品激情 | 亚洲成年影视网 | 成人网在线影片 | 天堂在线观看视频 | 国产第六页|