日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL优化之列裁剪和投影消除

發(fā)布時間:2023/12/20 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL优化之列裁剪和投影消除 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  列裁剪

  對于沒用到的列,則沒有必要讀取它們的數(shù)據(jù)去浪費無謂的IO

  比如我們有一張表table1,它含有四列數(shù)據(jù)(a,b,c,d)。當我們執(zhí)行查詢select a from table1 where c 10時,我們可以清晰的看到,table1中只有a,c兩列被用到了。分別是Selection算子用到c列和Projection算子用到a列。那么DataSource讀取數(shù)據(jù)時,b,d兩列則不需要讀取,可以裁剪掉。

  那么都有哪些算子與列有關系呢?綜合我們多年來使用SQL的經(jīng)驗來看,Selection(Where 條件)、Projection(搜索的列)、Sort(排序列)、Join(等值連接)、Aggregation(Group By及相關聚合操作)等。

  列裁剪的算法就是自頂向下的把算子過一遍,某個節(jié)點需要用到的列就等于它自己需要用到的列加上它的父節(jié)點所需要用到的列。這樣得到整個SQL語句所涉及到的列,從而再讀取數(shù)據(jù)時只讀取需要的列即可。

  列裁剪通過只讀取需要的數(shù)據(jù)減少IO操作來達到優(yōu)化的目的

  投影消除

  投影消除是把不必要的Projection給消除掉

  那么問題來了,什么情況下,投影算子是可以被消除的呢?

  如何Projection算子需要投影的列跟子節(jié)點的輸出列一樣,那么這個投影就是一個廢操作,可以被消除掉。比如說:select a,b from table1 如果再表table1中剛好只有a,b兩列,也就是DataSource的輸出和Projection需要投影的列一樣,那么這時候就沒必要在TableScan之后再做一次Projection操作了。

  如果Projection的子節(jié)點還是Projection的話,那么子節(jié)點的Projection就沒有意義了,可以干掉。如:select a from (select a,b,c from table2) 這條語句里面有兩個Projection,分別是最上層的Projection(a)和它的子節(jié)點Projection(a,b,c)。那么Projection(a,b,c)這個節(jié)點就是廢操作,可以被消除掉。

  Aggregation在某種意義上也屬于投影操作,因為從這個節(jié)點出來的都是列的概念,比如Max(a)、Min(b)等。因此在Aggregation-Projection的過程中,這個Projection也是可以被消除掉的。

  所以說,一個節(jié)點是否可以被消除,一方面是由它的父節(jié)點告訴它,它是否是一個冗余的Projection操作。另一方面是它自己和孩子節(jié)點做比較,看自身是否可以被消除。

  public void eliminate(Plan plan, boolean canEliminate) {

  //如果plan為Projection則判斷是否需要被消除

  if (plan is Projection) {

  //如果父節(jié)點調用時指定canEliminate為true,則進行消除操作

  if (canEliminate) {

  doEliminate(plan);

  }

  //如果plan的輸出和子節(jié)點的輸出一樣則消除plan

  if (checkPlanOutEqualsNext(plan)) {

  doEliminate(plan);

  }

  }

  //遞歸調用,遍歷子節(jié)點

  eliminate(plan.next(), checkPlanNextCanEliminate(plan));

  }

  最大最小消除

  最大最小消除嚴格上說不是標準邏輯優(yōu)化里面需要做的事情

  舉個栗子:

  語句1select min(a) from table1可以轉換為語句2select a from table1 order by a desc limit 1

  語句1生成的邏輯執(zhí)行計劃是一個 TableScan 上面接一個 Aggregation,也就是說這是一個全表掃描的操作。

  語句2生成的邏輯執(zhí)行計劃是TableScan + Sort + Limit,在某些情況,比如a是主鍵或者是存在索引,數(shù)據(jù)本身是有序的, Sort 就可以消除,最終變成 TableScan 或者 IndexLookUp 加 Limit,這樣子就不需要全表掃了,讀到第一條數(shù)據(jù)就得到結果!全表掃跟只查一條數(shù)據(jù),查詢速度可是天壤之別。也許這一點點寫法上的區(qū)別,就是幾分鐘甚至更長,跟毫秒級響應的差距。

  最大最小消除就是SQL優(yōu)化器自動把上面的操作實現(xiàn)了。比如說:

  select max(id) from table1 生成的查詢計劃會變成下面這種(最大消除):

  select max(id) from (select id from table1 order by id desc limit 1 where id is not null) t

  select min(id) from table1生成的查詢計劃會變成下面這種(最小消除):

  select min(id) from (select id from table1 order by id limit 1 where id is not null) t

  然后轉換后的語句再經(jīng)過其他的轉換規(guī)則最終得到最后的查詢計劃。

?


轉載于:https://juejin.im/post/5c6cfa926fb9a049ac79be11

總結

以上是生活随笔為你收集整理的SQL优化之列裁剪和投影消除的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。