HQL底層原理及優化:1 干預SQL的運行方式 之1.2通過Hint對計算引擎執行過程進行干預

Hint,意爲提示。

1 Hint簡介

本小節參考自文章Oracle hint詳解中的一部分,感謝原作者的分享。

1.1 爲什麼引入Hint?

Hint是Oracle數據庫中很有特色的一個功能,是很多DBA優化中經常採用的一個手段。那爲什麼Oracle會考慮引入優化器呢?基於代價的優化器是很聰明的,在絕大多數情況下它會選擇正確的優化器,減輕DBA的負擔。

但有時它也聰明反被聰明誤選擇了很差的執行計劃,使某個語句的執行變得奇慢無比。此時就需要DBA進行人爲的干預,告訴優化器使用指定的存取路徑或連接類型生成執行計劃,從而使語句高效地運行。Hint就是Oracle提供的一種機制,用來告訴優化器按照告訴它的方式生成執行計劃。

1.2 不要過分依賴Hint

當遇到SQL執行計劃不好的情況,應優先考慮統計信息等問題,而不是直接加Hint了事。如果統計信息無誤,應該考慮物理結構是否合理,即沒有合適的索引。只有在最後仍然不能SQL按優化的執行計劃執行時,才考慮Hint。

畢竟使用Hint,需要應用系統修改代碼,Hint只能解決一條SQL的問題,並且由於數據分佈的變化或其他原因(如索引更名)等,會導致SQL再次出現性能問題

1.3 Hint的弊端

Hint是比較"暴力"的一種解決方式,不是很優雅。需要開發人員手工修改代碼。
Hint不會去適應新的變化。比如數據結構、數據規模發生了重大變化,但使用Hint的語句是感知變化併產生更優的執行計劃。
Hint隨着數據庫版本的變化,可能會有一些差異、甚至廢棄的情況。此時,語句本身是無感知的,必須人工測試並修正。

1.4 Hint與註釋關係

提示是Oracle爲了不破壞和其他數據庫引擎之間對SQL語句的兼容性而提供的一種擴展功能。Oracle決定把提示作爲一種特殊的註釋來添加。它的特殊性表現在提示必須緊跟着DELETE、INSERT、UPDATE或MERGE關鍵字

換句話說,提示不能像普通註釋那樣在SQL語句中隨處添加。且在註釋分隔符(/*)之後的第一個字符必須是加號。在後面的用法部分,會詳細說明。

1.5 語法

  • DELETE、INSERT、SELECT和UPDATE是標識一個語句塊開始的關鍵字,包含提示的註釋只能出現在這些關鍵字的後面,否則提示無效。
  • "+“號表示該註釋是一個提示,該加號必須立即跟在”/*"的後面,中間不能有空格。
  • hint是下面介紹的具體提示之一,如果包含多個提示,則每個提示之間需要用一個或多個空格隔開。
  • text是其它說明hint的註釋性文本

在Oracle中的Hint有許多種,Hive中的Hint尚未廣泛瞭解,以後再補充。

2 使用MapJoin Hint的SQL

Hive Map Join
MapJoin通常用於一個很小的表和一個大表進行join的場景,具體小表有多小,由參數 hive.mapjoin.smalltable.filesize來決定,該參數表示小表的總大小,默認值爲25000000字節,即25M.
Hive0.7之前,需要使用hint提示* /+ mapjoin(table) */纔會執行MapJoin,否則執行Common Join,但在0.7版本之後,默認自動會轉換Map Join,由數 **hive.auto.convert.join來控制,默認爲true.
仍然以9.1中的HQL來說吧,假設a表爲一張大表,b爲小表,並且hive.auto.convert.join=true,那麼Hive在執行時候會自動轉化爲MapJoin。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章