一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Oracle - Cursor共享哪些事,你知道哪些?

Cursor共享哪些事,你知道哪些?

2023-12-05 08:33未知服務器之家 Oracle

早些年搞Oracle的時候,最讓人頭疼的事情就是和共享池相關的,而共享池里遇到問題最多的事情大多數是和SQL編譯相關的,關于十多年前這方面的往事我最近總想寫一篇Oracle往事來給大家介紹一下。 Oracle共享池最初是為了全局共享

早些年搞Oracle的時候,最讓人頭疼的事情就是和共享池相關的,而共享池里遇到問題最多的事情大多數是和SQL編譯相關的,關于十多年前這方面的往事我最近總想寫一篇Oracle往事來給大家介紹一下。

Oracle共享池最初是為了全局共享SQL執行計劃而設計的,全局共享執行計劃可以最大限度的減少SQL解析,在高并發的系統中提升數據庫的整體并發能力,這對于二三十年前的計算機硬件來說至關重要。其實除了Oracle之外,那個時代發展起來的商用數據庫大多也支持全局SQL執行計劃共享,比如SQL SERVER 的Parameterized Query Plan Caching。

全局SQL PLAN共享并不是數據庫必須具備的功能,也不是所有的數據庫都支持全局SQL PLAN共享,MySQL、Postgresql等開源數據庫以及絕大多數國產數據庫都是會話級共享SQL PLAN的。會話級共享SQL PLAN可能沒有全局共享效果好,不過MySQL、PG這些數據庫在設計之初并沒有考慮在復雜業務場景下的超高并發執行問題,因此全局共享SQL PLAN并不是其涉及要點。采用會話級共享執行計劃減少了數據字典相關的鎖以及字典緩沖的閂鎖爭用,有效的降低了SQL解析器的復雜度,有助于數據庫更穩定的運行,特別是在數據字典不太發生變化的場景中。隨著現代硬件的快速發展,在大多數情況下,SQL解析所消耗的系統資源已經不成為主要的問題了,因此沒有使用全局SQL PLAN CACHE的開源數據庫在絕大多數高并發量執行的場景中也都能夠勝任。在我所遇到的運維案例中,反而是采用全局執行計劃共享的Oracle數據庫經常在負載不算太高的場景中,比如每秒幾萬次執行的場景中,因為硬解析過多而觸發了shared pool、Library cache 、cursor mutex等方面的爭用,引發了較為嚴重的性能問題。

不管如何,共享執行計劃(全局和會話級)確實有效的提高了數據庫在SQL解析方面的效率,從而可以更好的支撐高并發場景和一些數據字典經常發生變更的高并發場景。不同的數據庫共享SQL PLAN的實現方式差異很大,Oracle使用家傳的共享池,隨著Oracle數據庫的發展,共享池已經變成了一個極其極其復雜的全局共享數據結構,不僅僅用于SQL PLAN共享,其全局內存堆(KGH)管理的模式是統一的。其他數據庫一般使用相對簡單一點的SQL PLAN CACHE來實現執行計劃共享。    

實現執行計劃共享遇到的第一個問題是SQL使用非綁定變量的問題,最初的SQL共享完全是基于SQL文本的,其原理是對SQLTEXT做一個HASH函數,HASH值相同的SQL被認為是相同的,可以共享的。如果我們在SQL中直接使用常量值而沒有使用綁定變量,那么SQL是無法共享的。Oracle在早期想要共享cursor,必須強制開發人員在編程時使用綁定變量。但是開發人員的水平參差不齊,經常會忘記這個開發規范。于是Oracle通過cursor_sharing參數對SQL進行簽名處理。自動將相似的SQL進行歸并,從而讓SQL能夠最大限度的共享。哪怕寫程序是沒有使用綁定變量,SQL解析器會自動幫你完成這個工作。

通過cursor_sharing自動處理非綁定變量的SQL或者使用綁定變量一定是件好事情嗎?也不一定是這樣的,如果某條SQL只有一個最佳的SQL PLAN,這是沒有問題的。不過在現實中可能存在相同的SQL有多種最好的執行計劃的情況存在。比如下面這個例子。    

Cursor共享哪些事,你知道哪些?圖片

當Object_id為20的時候,記錄數有419萬行數據,因此全表掃描是比較合理的執行計劃。

Cursor共享哪些事,你知道哪些?圖片

而當Object_id=21的時候,返回數據只有16行,因此此時使用索引范圍掃描是比較合理的執行計劃。而如果我們使用綁定變量,select object_name from t1 where object_id=:p,這樣兩種情況如果共享執行計劃,那就明顯是不合理的。    

這種情況下如果共享執行計劃,那么可能會出現十分怪異的情況。比如說同一條SQL有時候走索引,有時候走全表掃描。有時候突然就會大量SQL不走索引全部走執行計劃了。甚至出現同一條SQL在不同RAC節點上,一個節點是走索引的,另一個節點上死活不走索引。其實明白了SQL共享與SQL解析的原理就很清楚了。在解析帶有綁定變量或者通過cursor_sharing進行共享的SQL的時候,會進行綁定變量的窺探,編譯時帶入的參數就決定了執行計劃最終走不走索引。而下一回同一條可共享的SQL執行的時候,就不會再去窺探參數了,因此就會導致不必要的SQL執行計劃錯誤。

為了解決這個問題,Oracle推出了Adaptive Cursor Sharing(ACS)。在ACS技術的加持下如果存在數據偏斜,ACS 能夠識別不同的綁定變量值具有不同的選擇性,從而選擇最為合理的執行計劃。

當帶有綁定變量的 SQL 語句首次被解析時,優化器會窺探綁定變量的值,并根據謂詞的選擇性生成一個執行計劃,同時把該游標標記為 bind-sensitive(綁定敏感的)。當同樣的 SQL 語句再次被執行時,優化器會比較當前綁定變量的值和之前的值,如果發現選擇性有顯著差異,優化器可能會創建一個新的子游標和執行計劃,同時把該游標標記為 bind-aware(綁定感知的)。當同樣的 SQL 語句再次被執行時,優化器會根據綁定變量的值的選擇性范圍,匹配最合適的子游標和執行計劃,從而避免使用不適合的執行計劃。

目前Oracle ACS可以在絕大多數場合下解決cursor共享的問題,不過ACS也存在一定的負面作用。比如會增加每次SQL執行的開銷,同時會讓一個CURSOR產生過多的不共享的執行計劃,從而影響這個CURSOR的執行效率,增加MUTEX爭用,嚴重時會引發系統性能問題。因此在某些應用場景中,用戶會選擇關閉ACS功能。

看到這里可能大多數朋友都會覺得我今天還是在炒Oracle ACS的冷飯,如果能看到這里的朋友,今天算是來對了。前面的近兩千字的鋪墊,只是為了讓人更好地理解今天我想帶給大家的一些干貨。    

今天要帶給大家的第一點干貨是和Oracle ACS相關的。雖然很多數據庫不支持全局SQL PLAN CACHE,不過一般都支持會話級SQL PLAN CACHE。當某條SQL執行多次的時候,就不會再對這條SQL做解析,而直接復用緩沖中的執行計劃了。那么與ORACLE 類似的問題出現了,如果數據是不均衡的,有些時候要走索引,有些時候需要走全表掃描怎么辦?這種情況下,就會出現類似Oracle出現過的奇怪現象,某條SQL,有時候執行效率高,有時候執行效率低,而且我們無法控制。遇到這種情況,有時候可能就是因為SQL PLAN CACHE緩沖的執行計劃不一定適合某個場景的SQL。

有些用過Oracle的朋友可能會想到解決這個問題的辦法,那就不使用綁定變量,讓SQL PLAN無法共享。其實這個辦法在某些開源或者國產數據庫中并不一定有效。比如PG數據庫,默認就會對SQL進行簽名,自動轉換成綁定變量格式,就像Oracle數據庫里設置了cursor_sharing=FORCE。而且這些數據庫往往有不支持類似Oracle ACS的功能,因此使用非綁定變量來解決這個問題是無效的。

我們該如何解決這個問題呢?其實在Oracle占主導地位的時代,這個問題就已經有解了。如果我們關閉了ACS功能,但是確實存在某些場景中同樣的SQL帶入不同的參數時,需要有不同的執行計劃,該如何處理呢。遇到這種情況,我們就只能通過在SQL語句上加上注釋(/* PLAN B */),強制性的讓優化器把這條SQL區分為兩條不同的SQL。實際上,當Oracle還沒有推出ACS功能的時候,我們就是這樣在cursor_sharing=FORCE的數據庫里糾正錯誤的執行計劃的,這個方法對于MySQL、PG和一些國產數據庫依然有效。

今天的第二點干貨是關于分布式數據庫的,與集中式數據庫不同的是,分布式數據庫上的 硬解析的成本要高得多,因此在分布式數據庫中,盡可能要實現SQL PLAN CACHE。因此在分布式數據庫上,因為SQL PLAN CACHE引起的SQL PLAN CACHE中的執行計劃不適配的問題依然是存在的,并且在一些高負載的場景中,往往因為此類問題引發分布式集群范圍的性能問題。這種情況下,如果你能夠很快發現問題,并且將某個不合理的執行計劃從SQL PLAN CACHE中清除掉,很快就能解決數據庫集群的性能問題。    

周五的時候,張瑞遠先生就和我討論過一個在OB上遇到的SQL PLAN CACHE引發的執行計劃問題。經過分析發現OB默認的CURSOR_SHARING是FORCE,也就是說默認情況下,OB會自動對SQL進行簽名,將沒有使用綁定變量的SQL轉化為使用綁定變量的格式。如果訪問的數據存在較為嚴重的列傾斜現象,那么就會遇到SQL PLAN CACHE中的執行計劃不適用的問題。經過和OB的朋友一起討論,對OB中解決這個問題初步有了一個方案。首先在Oracle上使用 的PLAN B方案依然適用。如果某條SQL根據綁定變量不同,有少量的幾種情況可以明確區分,那么PLAN B方案是可行的。如果數據傾斜問題比較復雜,不能簡單的分類,那么在OB中可以通過HINT或者outlines,將這條SQL設置為不適用PLAN CACHE來規避這個問題。

在Oracle數據庫中,也有類似的HINT,在數據庫產品沒有ACS功能或者關閉了ACS功能的 時候,這是一種十分有效的方法。繞開PLAN CACHE可以讓本身就無法共享執行計劃的SQL不要去干擾PLAN CACHE,可以更好的保護全局PLAN CACHE。

沒想到今天寫著寫著就寫多了,數據庫的問題,每個小問題其實都夠復雜的,攤開了講,三五千字根本說不清楚,不過不要緊,花上幾年時間,一個個研究清楚,你也就成了高手了。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人免费在线视频 | 337p大尺度啪啪人体午夜2020 | 国产午夜免费不卡精品理论片 | 日本高清有码视频 | 羞羞视频免费观 | 日韩播放| 精东影业传媒全部作品 | 免费观看欧美性一级 | 色天天综合网色鬼综合 | 成年人在线免费观看视频网站 | 欧美日韩高清观看一区二区 | h网站国产| 国产欧美日韩成人 | 色综合视频一区二区三区 | 国产精品女主播自在线拍 | 日本韩国无矿砖码 | 国产成人精品日本亚洲网站 | 青草青草视频2免费观看 | 超级乱淫伦短篇在车上 | 教室里的激情电影 | 久久一本综合 | 青草热视频 | 色人阁导航| 日本视频在线观看播放 | 四虎4hu新地址入口 四虎1515h永久 | 日产乱码卡一卡2卡三卡四福利 | 9久re热视频这里只有精品 | 草莓丝瓜芭乐樱桃榴莲色多黄 | 日本另类z0zx高清 | 亚洲成人91| 日本不卡高清免费v日本 | 国产日产欧产精品精品软件 | 国产一二三区视频 | 嫩草视频在线观看视频播放 | 欧美一区二区三区四区五区六区 | 天天综合天天综合 | 天天爱综合网 | 国产欧美亚洲精品第一页青草 | 91porny新九色在线 | 大伊人青草狠狠久久 | 亚洲精品久久久992KVTV |