oracle 刪除主鍵_大數據量刪除的思考 4

b104099f14869fe88609a884de4282f2.png

譯者? 湯健 · 沃趣科技數據庫技術專家

出品 ?沃趣科技

c2ebd5e0df45ef286e12828ad9cb3568.png

575d98c78cda1fd61fc5b7fc6926e9e8.gif在本系列的前一期文章中,我制作了一些圖,突出顯示了按表掃描執行大量刪除操作和按索引范圍掃描執行大量刪除之間的主要區別。根據所涉及的數據模式,選擇正確的策略可能對隨機I/Os的數量、生成的undo的數量和排序所需的CPU數量產生顯著影響——所有這些都可能影響執行刪除所需的時間。然而,這個簡單的演示跟生產環境當中相比,生產環境當中這個情況更為復雜。所以,如果你面臨著一項艱巨的任務,你需要仔細考慮如何對真正代表你要處理的系統的東西進行建模。實際上有兩種不同的情況,這一點很重要。*當你在處理一個非常大的一次性任務時,你需要在第一時間就把它做好,一些關鍵性的特殊情況不要發現的太遲——尤其是如果你不允許把生產系統離線來完成這個任務任務,而且你的工作期限很緊的話。*當你有一份常規的、但不經常發生的、非常大的工作時,有必要了解一下哪些看起來不相關的小操作可能對運行時產生很大影響;而且,了解下一次升級可能會出現什么問題是值得的,這樣您就可以預先解決任何問題。當然,后者的一個簡單例子是我對12c的簡短評論,以及它通過索引快速全掃描來驅動刪除的能力-這一功能在早期版本的Oracle中無法運行。在我的小示例中,一個測試將其執行計劃從11g的索引全掃描更改為12c的索引快速全掃描,完成所需的時間是原來的兩倍。繼續想一想——當你試圖通過索引范圍掃描來刪除Oracle中的表或者索引時,您能想到多少事情,這可能會產生怎樣的影響?對于一個繁忙的系統,這個建議聽起來不錯。有時候,你會發現一個長時間運行的DML語句在運行時速度非常慢,因為事實上它涉及到數據中最近的部分,因此會受到當前變化的影響;從這一點來看,Oracle發現它必須讀取undo段來獲取undo數據,這使得創建與讀取一致的數據塊版本成為可能-它需要這樣做,以便它可以檢查當前和讀取一致的版本的塊同意哪些行應該刪除。我做的一個例子是通過“date_open”索引刪除數據-因此,如何強制索引進行降序范圍掃描,以便首先檢查最新的數據在它有很多(或任何)時間遭受其他DML的附帶損害之前?有一個非常快捷的方法可以檢驗這個想法的有效性。所以我們要做的就是檢查排序的行數和刪除的行數我們就能知道優化是否發生了。我的測試數據集有1000000行和4個索引(主鍵client_ref、date_open和date_closed索引),所以在最好的情況下,我應該看到:“sort (rows)”= 4 *行被刪除。下面是我做的一個測試的總結,我想知道會發生什么:
delete?/*+?index_desc(t1?t1_pk)?*/?from?t1?where?id?<=?5e6


5000000?rows?deleted.

Name?????????????????????????????????Value???????????????????????

----?????????????????????????????????-----
sorts?(rows)????????????????????????????29

我們刪除了500萬行并(有效地)沒有排序。當我們按降序遍歷索引時,優化根本不適用—我確實檢查了執行計劃是否顯示了我所指定的“索引范圍遞減掃描”。

create?index?t1_dt_open?on?t1(date_open?desc)?nologging?tablespace?test_8k_assm_2;
delete?/*+?index(t1?t1_dt_open)?*/?from?t1?where?date_open?<=?add_months(sysdate,?-60);

4999999?rows?deleted.

Name?????????????????????????????????Value
----?????????????????????????????????-----
sorts?(rows)????????????????????20,003,449

在副作用很小的范圍內,“sort (rows)”= 4 *已刪除的行:所以可以使用降序索引先嘗試刪除較新的數據——這很好,作為一個通用特性來記住可能很有用。

讓我們想象一下其他可能出錯的情況。*我在這個表上定義了一個主鍵——但是你可以使約束延遲,或者您可以簡單地創建一個非惟一索引來保護惟一(或主鍵)約束。如果我們試圖通過主鍵索引刪除,會產生什么影響?*如果我們要考慮約束,我們可能要考慮外鍵約束的影響——我們有一個client_ref列,在生產系統中,它可能是對clients表的外鍵引用。讓我們創建這個表并添加外鍵約束。*當我們使事情變得更困難時——有一個眾所周知的特性將數組處理轉換為“逐行”處理——觸發器。如果我們向表中添加行級觸發器,會產生什么效果?什么類型的觸發器(在之前/之后、插入/更新/刪除)有什么區別嗎?以下是一些結果-首先,主鍵約束的非唯一索引:
alter?table?t1?drop?primary?key;

alter?table?t1?add?constraint?t1_pk?primary?key(id)
deferrable?initially?immediate
using?index?nologging?tablespace?test_8k_assm_2
;

delete?/*+?index(t1?t1_pk)?*/?from?t1?where?id?<=?5e6;

5000000?rows?deleted.

Name?????????????????????????????????Value
----?????????????????????????????????-----
sorts?(rows)?????????????????????15,000,004

在這個例子中,Oracle將我的主鍵索引設置為非惟一,作為約束可延遲的副作用,但是即使約束不可延遲,并且您只是將索引創建為非惟一,其效果也是一樣的。統計數據告訴我們,我們已經將優化應用于四個索引中的三個——快速檢查一下v$segment_statistics,就會發現它是主鍵索引,沒有進行特殊處理,它受到了超過500萬個“db塊更改”的影響。在這一點上,有必要快速檢查一下,看看通過其他索引驅動是否會改變這種情況——但是不會,這是惟一約束與非惟一索引結合的副作用。

其次,當大表是“子表”時,引用完整性的影響:
create?table?t2?(
????????client_id,
????????client_name
)?as
select
????????distinct
????????????????client_ref,
????????????????rpad('x',100,'x')
from
????????t1
;
alter?table?t2?add?constraint?t2_pk?primary?key(client_id);
alter?table?t1?modify?client_ref?not?null;
alter?table?t1?add?constraint?t1_fk_t2?foreign?key?(client_ref)?references?t2(client_id);

5000000?rows?deleted.

Name?????????????????????????????????Value
----?????????????????????????????????-----
sorts?(rows)????????????????????15,002,849

我們已經排序了大約1500萬行,而通常我們需要排序2000萬行.同樣,我們可以檢查v$segment_statistics來找出哪個索引遭受了500萬的損失“db block changes”你可能不會對“外鍵”索引被逐行維護而感到驚訝-我們可能會猜測,這是某種先發制人的代碼使得Oracle必須處理“外鍵鎖定”威脅。

我們通過主鍵刪除這個特定測試的后續操作是,考慮如果我們通過外鍵索引本身刪除,或者甚至將約束修改為“on delete cascade”并刪除一些父行,將會發生什么。通過client_ref在t1上驅動delete仍然優化了其他三個索引,但是當您試圖利用“on delete cascade”機制時,這個技巧根本沒有機會產生大規模的效果。在幕后你會發現這樣的事情:
delete?from?"TEST_USER"."T1"
where
?"CLIENT_REF"?=?:1


call?????count???????cpu????elapsed???????disk??????query????current????????rows
-------?------??--------?----------?----------?----------?----------??----------
Parse????????3??????0.00???????0.00??????????0??????????0??????????0???????????0
Execute???3000??????5.23??????15.37??????69349???????9238?????428052???????32510
Fetch????????0??????0.00???????0.00??????????0??????????0??????????0???????????0
-------?------??--------?----------?----------?----------?----------??----------
total?????3003??????5.23??????15.37??????69349???????9238?????428052???????32510


Rows?(1st)?Rows?(avg)?Rows?(max)??Row?Source?Operation
----------?----------?----------??---------------------------------------------------
?????0??????????0??????????0??DELETE??T1?(cr=3?pr=22?pw=0?time=9672?us)
?????7??????????8?????????11???INDEX?RANGE?SCAN?T1_CLIENT?(cr=3?pr=0?pw=0?time=125?us?cost=3?size=594?card=22)(object?id?150589)

This?output?the?consequence?of?a?bulk?delete?of?3,000?rows?from?t2?–?because?of?the?“on?delete?cascade”,?the?delete?operated?row?by?row?on?t2?and?for?each?row?Oracle?executed?a?delete?statement?against?t1.

這個輸出是t2批量刪除3000行的結果——由于“on delete cascade”,delete在t2上逐行操作,對于每一行Oracle都對t1執行一條delete語句。

從技術上講,基于數組的優化是有效的,由于索引范圍掃描,它給我們帶來了一點好處,但是數據的分散性是如此之大,以至于每次調用幾乎沒有給我們帶來任何好處。在某個階段,我們將不得不進一步探索這種父/子的關系。最后是觸發器。眾所周知,行級觸發器可以將數組處理轉換為單行處理——Oracle的索引維護優化也會發生同樣的事情嗎?
create?or?replace?trigger?t1_brd
before?delete?on?t1
for?each?row
begin
????null;
end;
/


delete?/*+?index(t1?t1_pk)?*/?from?t1?where?id?<=?5e6;

5000000?rows?deleted.

Name?????????????????????????????????Value
----?????????????????????????????????-----
sorts?(rows)?????????????????????????2,639

優化完全消失了。同樣的事情也會發生在“為每一行刪除后”觸發器上,但是如果觸發器是insert或update(行級)觸發器,則不會發生這種情況。值得一提的是,索引優化也發生在索引列的值發生變化的更新上(請參閱本文),因此留給感興趣的讀者一個練習,看看哪些(如果有的話)觸發器類型允許優化在數組更新后繼續存在。

| 譯者簡介

湯健·沃趣科技數據庫技術專家

沃趣科技數據庫工程師,多年Oracle數據庫從業經驗,深入理解Oracle數據庫結構體系,現主要參與公司一體機產品安裝、測試、優化,并負責電信行業數據庫以及系統運維。

相關鏈接

MySQL 一個讓你懷疑人生的hang死現象

MySQL 執行DDL語句 hang住了怎么辦?

MySQL行級別并行復制能并行應用多少個binlog group?

binlog server還是不可靠嗎?

MySQL binlog基于時間點恢復數據失敗是什么鬼?

開源監控系統Prometheus的前世今生

prometheus監控多個MySQL實例

MySQL問題兩則

Kubernetes?scheduler學習筆記

大數據量刪除的思考(三)

大數據量刪除的思考(二)

大數據量刪除的思考(一)

統計信息記錄表|全方位認識 mysql 系統庫

數據庫對象信息記錄表|全方位認識 mysql 系統庫

訪問權限控制系統|全方位認識 mysql 系統庫

權限系統表?|?全方位認識?mysql?系統庫

Oracle RAC Cache Fusion 系列十四:Oracle RAC CR Server Part One

Oracle RAC Cache Fusion 系列十三:PCM資源訪問

Oracle RAC Cache Fusion 系列十二:Oracle RAC Enqueues And Lock Part 3

Oracle RAC Cache Fusion 系列十一:Oracle RAC Enqueues And Lock Part 2

Oracle RAC Cache Fusion 系列十:Oracle RAC Enqueues And Lock Part 1

928b669ac987bcd11537db46df571c1a.png

更多干貨,歡迎來撩~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396601.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396601.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396601.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

redis 持久化 + 主從復制+ 集群

2019獨角獸企業重金招聘Python工程師標準>>> 一、 Linux 下的 Redis 安裝 && 啟動 && 關閉 && 卸載 http://blog.csdn.net/zgf19930504/article/details/51850594 注&#xff1a;設置 redis.conf bind***.***.*.(127.0.0.1) redis啟動&…

怎么運行c語言_C語言 原來是這樣調用硬件的

大家都知道我們可以使用C語言寫一段程序來控制硬件工作&#xff0c;但你知道其工作原理嗎&#xff1f;網友北極C語言在實際運行中&#xff0c;都是以匯編指令的方式運行的&#xff0c;由編譯器把C語言編譯成匯編指令&#xff0c;CPU直接執行匯編指令。所以這個問題就變成&#…

四、元祖、字典

一、元祖(tuple)&#xff1a;tu(11,"hello",(0,1),[11,"111"],33,) 元祖的特點&#xff1a;元祖中一級元素不可被修改&#xff0c;不能被增加或刪除&#xff0c;多級元素可以被修改&#xff0c;一般寫元祖的時候&#xff0c;推薦在后面添加逗號“&#xff…

PHP編程效率的20個要點

用單引號代替雙引號來包含字符串&#xff0c;這樣做會更快一些。因為PHP會在雙引號包圍的字符串中搜尋變量&#xff0c;單引號則 不會&#xff0c;注意&#xff1a;只有echo能這么做&#xff0c;它是一種可以把多個字符串當作參數的“函數”(譯注&#xff1a;PHP手冊中說echo是…

ubuntu運行python ide_打造vim中的python IDE

首先先介紹幾個常用的插件&#xff1a;1&#xff0c;ctags和taglist&#xff0c;這個大家估計都很常用&#xff0c;在ubuntu下只要安裝exuberant-ctags即可啦&#xff0c;另外tagbar支持面向對象語言的展示" toggle Tagbar displaymap :TagbarToggle" autofocus on T…

更新和插入的并發問題_mysql經典面試題:如何讀寫分離?主從原理是啥?同步的延時問題...

面試題你有沒有做 MySQL 讀寫分離&#xff1f;如何實現 MySQL 的讀寫分離&#xff1f;MySQL 主從復制原理的是啥&#xff1f;如何解決 MySQL 主從同步的延時問題&#xff1f;考點分析高并發這個階段&#xff0c;肯定是需要做讀寫分離的&#xff0c;啥意思&#xff1f;因為實際上…

php實現一個簡單的四則運算計算器

php實現一個簡單的四則運算計算器&#xff08;還不支持括號的優先級&#xff09;。利用棧這種數據結構來計算表達式很贊。 這里可以使用棧的結構&#xff0c;由于php的數組“天然”就有棧的特性&#xff0c;這里直接就利用了數組。當然可以使用棧結構寫&#xff0c;道理一樣的。…

Tcp與Ip協議的客戶端和服務器編程

Tcp與Ip協議的客戶端和服務器編程 本文就TCP和Ip協議的客戶端和服務器分別進行編程&#xff0c;實現了客戶端和服務端進行通信的功能&#xff0c;服務端對多個客戶端進行監聽&#xff0c;并能與多個客戶端通信。 服務器端代碼如下&#xff1a; using System; using System.Coll…

maven建立webapp項目時顯示Cannot change version of project facet Dynamic web module to 2.5

為什么80%的碼農都做不了架構師&#xff1f;>>> 網上查了很多東西都沒啥用&#xff0c;其實直接把這段代碼加到web.xml頭部&#xff0c;自然就不報錯了 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.…

python數據結構算法 北京大學_北京大學公開課《數據結構與算法Python版》

之前我分享過一個數據結構與算法的課程&#xff0c;很多小伙伴私信我問有沒有Python版。看了一些公開課后&#xff0c;今天特向大家推薦北京大學的這門課程&#xff1a;《數據結構與算法Python版》。課程概述很多同學想要轉行機器學習&#xff0c;也確實掌握了一些機器學習模型…

20道C#練習題(一)1——10題

1.輸入三個整數&#xff0c;xyz&#xff0c;最終以從小到大的方式輸出。利用if嵌套。 Console.Write("請輸入x"); double x double.Parse(Console.ReadLine()); Console.Write("請輸入y"); double y double.Parse(Console.ReadLine()); Console.Write(&q…

fd 句柄_linux文件描述符fd(windows下的句柄)

在Linux系統中一切皆可以看成是文件&#xff0c;文件又可分為&#xff1a;普通文件、目錄文件、鏈接文件和設備文件fd&#xff1a;file descriptor文件描述符0,1,2分別給了標準輸入、標準輸出和錯誤輸出。ls -l /proc/pid/fd可以查看某個進程所使用的fd用lsof可以查看比如&…

Python——三級菜單

#三級菜單函數 menu {北京&#xff1a;&#xff5b;海淀&#xff1a;&#xff5b;五道口&#xff1a;&#xff5b;&#xff5d;中關村&#xff1a;&#xff5b;&#xff5d;上帝&#xff1a;&#xff5b;&#xff5d;&#xff5d;昌平&#xff1a;&#xff5b;&#xff5d;朝陽…

HTTPS 原理解析

http://www.cnblogs.com/zery/p/5164795.html 一 前言 在說HTTPS之前先說說什么是HTTP&#xff0c;HTTP就是我們平時瀏覽網頁時候使用的一種協議。HTTP協議傳輸的數據都是未加密的&#xff0c;也就是明文的&#xff0c;因此使用HTTP協議傳輸隱私信息非常不安全。為了保證這些隱…

python 函數參數注解_python-如何使用函數注釋來驗證函數調用類...

我最近才發現有一種叫做函數注釋的東西,但是我不太確定如何使用它.這是我到目前為止的內容&#xff1a;def check_type(f):def decorated(*args, **kwargs):counter0for arg, type in zip(args, f.__annotations__.items()):if not isinstance(arg, type[1]):msg Not the vali…

SQL Server Replication 中關于視圖的點滴

在服務器A數據庫TEST新建了一個本地發布&#xff08;Local Publications&#xff09;RPL_GES_MIS_TEST,在服務器B數據庫RPL_TEST上創建了一個本地訂閱&#xff08;Local Subscriptions&#xff09;&#xff0c;它訂閱了了這個發布RPL_GES_MIS_TEST.如下截圖所示&#xff0c;本地…

kbmmw 5.0 中的REST 服務

目前關于REST 服務的話題越來越熱&#xff0c;kbmmw 在5.0 里面開始支持rest。今天我就試一下kbmmw 的 rest 服務。閑話少說&#xff0c;開始。 老規矩&#xff0c;放上兩個kbmMWServer1和 kbmMWHTTPSysServerTransport1兩個控件。 設置kbmMWHTTPSysServerTransport1的server 屬…

php7 匿名繼承類_PHP7匿名類的用法示例

本文實例講述了PHP7匿名類的用法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;/*** Created by PhpStorm.* User: Itboot* Date: 2019/1/17* Time: 18:15*/class An{private $num;protected $age 15;public function __construct() {$this->num 1;}protected f…

python中不需要函數重載的原因

函數重載主要是為了解決兩個問題&#xff1a; 1.可變參數類型 2.可變參數個數 并且函數重載一個基本的設計原則是&#xff0c;僅僅當兩個函數除了參數類型和參數個數不同以外&#xff0c;其功能是完全相同的&#xff0c;此時才使用函數重載&#xff0c;如果兩個函數的功能其實不…

多租戶saas 架構_[譯/注] Force.com 多租戶互聯網應用開發平臺的設計

原文地址 http://cloud.pubs.dbs.uni-leipzig.de/sites/cloud.pubs.dbs.uni-leipzig.de/files/p889-weissman-1.pdf譯注&#xff1a;原文發表于 ACM&#xff0c;2009年6月作者Craig D Weissman, CTO, Salesforce.comSteve Bobrowski, Technical Marketing Consultant, Salesfor…