從 TPCH 測試學習效能優化技巧之 Q2

2021-10-04 21:07:23 字數 4164 閱讀 1189

q2語句查詢獲得最小代價的供貨商。得到給定的區域內,對於指定的零件(某一型別和大小的零件),哪個**商能以最低的****它,就可以選擇哪個**商來訂貨。

q2語句的特點是:帶有排序、聚集操作、子查詢並存的多表查詢操作。查詢語句沒有從語法上限制返回多少條元組,tpc-h標準規定,查詢結果只返回前100行即可(通常依賴於應用程式實現)。

oracle編寫的查詢sql語句如下:

select * from (

select   /*+ parallel(n) */

s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment

from part,supplier,partsupp,nation,region

where

p_partkey = ps_partkey

and s_suppkey = ps_suppkey

and p_size = 25

and p_type like '%copper'

and s_nationkey = n_nationkey

and n_regionkey = r_regionkey

and r_name = 'asia'

and ps_supplycost = (

select

min(ps_supplycost)

from

partsupp,

supplier,

nation,

region

where

p_partkey = ps_partkey

and s_suppkey = ps_suppkey

and s_nationkey = n_nationkey

and n_regionkey = r_regionkey

and r_name = 'asia'

order by

s_acctbal desc,n_name,s_name,p_partkey

where rownum <= 100;

其中/*+ parallel(n) */ 是oracle的並行查詢語法,n是並行數。

指令碼執行時間,單位:秒

並行數124

812oracle

5635

231627

仔細分析這句sql,如果把子查詢

select

from

part,

partsupp,

supplier,

nation,

region

where

p_partkey = ps_partkey

and s_suppkey = ps_suppkey

and s_nationkey = n_nationkey

and n_regionkey = r_regionkey

and r_name = 'asia'

and p_size = 25

and p_type like '%copper'

看成是某個檢視v,原來查詢主體可以改寫成:

select   /*+ parallel(n) */

s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment

from v

where

ps_supplycost = (

select

min(ps_supplycost)

from

v v1

where

v.p_partkey = v1.p_partkey

這樣將原查詢變成乙個單錶查詢,相當於找出v中這樣一些記錄,使得這些記錄的ps_supplycost值在所有與該記錄的partkey值相同的記錄中取值最小。這個運算的本質是對v按partkey分組後對每組聚合,計算出每組中ps_supplycost最小的那條記錄。但是,sql不支援這種聚合運算,於是只能寫成子查詢的情況(即使轉換成單錶運算後)。

如果資料庫優化引擎不好,嚴格按這個子查詢描述的方法去遍歷計算,就會導致n*n的複雜度(n是v的記錄數);即使資料庫優化引擎較好,也需要先對v按partkey分組求ps_supplycost的最小值後做形成中間結果集再做索引,然後再次遍歷v,計算量也不少。

解決這個問題更好的辦法就是支援這種返回記錄本身的聚合計算,一次分組聚合即可完成運算。spl有集合和引用資料型別,也支援聚合出最小值所在記錄的聚合運算,可以實現這個想法,整體複雜度就會低很多。

spl指令碼如下:a1

=12>size=25

3>type="*copper"

4>name="asia"

5=now()

6=file(path+"region.ctx").create().cursor().select(r_name==name).fetch()

7=file(path+"nation.ctx").create().cursor().switch@i(n_regionkey,   a6:r_regionkey).fetch().keys@i(n_nationkey)

8=file(path+"part.ctx").create().cursor@m(p_partkey,p_mfgr;p_size==size   && like(p_type,type);a1).fetch().keys@i(p_partkey)

9=file(path+"supplier.ctx").create().cursor@m(s_suppkey,s_name,s_address,s_nationkey,s_phone,s_acctbal,s_comment;s_nationkey:a7;a1)

10=a9.fetch().keys@i(s_suppkey)

11=file(path+"partsupp.ctx").create().cursor@m(ps_partkey,ps_suppkey,ps_supplycost;ps_partkey:a8,ps_suppkey:a10;a1)

12=a11.groups(ps_partkey;top(1;ps_supplycost):rs).conj(rs)

13=a12.new(ps_suppkey.s_acctbal,ps_suppkey.s_name,ps_suppkey.s_nationkey.n_name,ps_partkey.p_partkey,ps_partkey.p_mfgr,ps_suppkey.s_address,ps_suppkey.s_phone,ps_suppkey.s_comment)

14=a13.sort(s_acctbal:-1,n_name,s_name,p_partkey).to(100)

15=now()

16=interval@s(a5,a15)

需要解釋的是,spl相對於sql更底層一些,spl不象sql有元資料概念,也沒有系統級的表概念,資料訪問直接從檔案開始讀取資料,這時前面準備資料的**就顯得稍微冗長一點。實際應用中可以通過使用spl預定義全程變數或虛表語法來簡化,達到類似sql直接使用資料表的效果。但這不是本篇的重點,而且為了讓讀者更方便地看出資料的原始流向,這裡就採用了直接檔案訪問的語法。

**中a6-a11用於定義上述檢視v的游標,a12中用groups內的top函式實現分組的同時聚合出最小值所在記錄(而不是最小值本身)。

a7中的switch@i函式將把外來鍵不能匹配的記錄過濾掉,同時將能匹配的關聯字段轉換成外來鍵表記錄的指標,這樣在後面可以直接用.的形式訪問外來鍵表的字段。spl看待join運算的思路和sql不一樣,如果資料能事先載入進記憶體,spl以利用預關聯提高運算效能。不過,本系列例子均假定從外訪問數計算,本問題中spl和sql在join運算效能也沒有演算法上的區別,只是寫法不同。詳細解釋可參考spl教案中關於join的部分。

另外,在a8中也使用了q1中提到的在游標建立時使用過濾條件的技巧。a9和a11中將這個技巧與前面的switch@i方法結合起來(第2組引數),在游標建立時做外來鍵匹配,不能匹配者直接過濾掉,不再讀取其它欄位且不再生成該記錄,能匹配時則將關聯字段轉換成指標。

指令碼執行時間,單位:秒

並行數124

812oracle

5635

2316

27spl組表

201485

4這個問題的資料量不大,幾次執行後,作業系統可以把資料都快取進記憶體,列存在這裡不是重點,帶來的訪問量優勢可以忽略,效能優勢主要是演算法優化帶來的。

從表中還能看出,這種分組聚合的並行效果也較好。

從 TPCH 測試學習效能優化技巧之 Q16

q16語句查詢獲得能夠以指定的貢獻條件 零件的供貨商數量。可用於決定在訂單量大,任務緊急時,是否有充足的供貨商。q16語句的特點是 帶有分組 排序 聚集 去重 not in子查詢操作並存的兩表連線操作。oracle編寫的查詢sql語句如下 select parallel n p brand,p ty...

從 TPCH 測試學習效能優化技巧之 Q19

q19語句查詢得到對一些空運或人工運輸零件三個不同種類的所有訂單的總折扣收入。零件的選擇考慮特定品牌 包裝和尺寸範圍。q19語句的特點是 帶有聚集 in子查詢操作並存的三表連線操作。oracle編寫的查詢sql語句如下 select parallel n sum l extendedprice 1 ...

1 學習效能優化的要點

效能分析本質是找出應用或者系統的瓶頸並設法避免或者緩解它們,從而更高效的利用系統資源處理更多的請求。1 從應用負載的角度來說,直接影響產品終端的效能。隨著應用負載的增加,系統的資源公升高甚至到達極限。2 從系統資源視角出發,比如資源的使用率和飽和度等 1.選擇指標評估應用程式和系統的效能。比如cpu...