亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

外鍵上有無索引的影響

發布時間:2020-08-13 05:17:26 來源:ITPUB博客 閱讀:203 作者:數據和云 欄目:關系型數據庫

原文鏈接: https://www.modb.pro/db/22800

摘要:今天在摩天輪上看到一個問題,《oracle外鍵無索引為什么會導致死鎖》,為什么呢? 現在通過一些簡單的案例來測試一下,外鍵索引和鎖的關系。

一、環境模擬

1、創建父表dept,主鍵deptno

SQL> create table dept(deptno number,dname varchar2(20),  2  constraint pk_dept primary key (deptno)  3  );
Table created.
SQL>

2、創建子表emp,主鍵empno,外鍵deptno

SQL> create table emp(empno number,ename varchar2(20),deptno number,  2  constraint pk_emp primary key (empno),  3  constraint fk_deptno foreign key (deptno) references dept (deptno)  4  );
Table created.
SQL>

3、插入數據

SQL> insert into dept select deptno,dname from scott.dept;
4 rows created.
SQL> insert into emp select empno,ename,deptno from scott.emp;
14 rows created.
SQL> commit;Commit complete.SQL> select * from dept;
    DEPTNO DNAME---------- ----------------------------------------
        10 ACCOUNTING
        20 RESEARCH
        30 SALES
        40 OPERATIONS
SQL> select * from emp;
     EMPNO ENAME                                        DEPTNO---------- ---------------------------------------- ----------
      7369 SMITH                                            20
      7499 ALLEN                                            30
      7521 WARD                                             30
      7566 JONES                                            20
      7654 MARTIN                                           30
      7698 BLAKE                                            30
      7782 CLARK                                            10
      7788 SCOTT                                            20
      7839 KING                                             10
      7844 TURNER                                           30
      7876 ADAMS                                            20
      7900 JAMES                                            30
      7902 FORD                                             20
      7934 MILLER                                           10
14 rows selected.
SQL>

二、模擬測試–外鍵無索引

session 1:在子表上插入一條記錄,不提交

SQL> select userenv('sid') from dual;
USERENV('SID')--------------
           170

SQL> insert into emp values(3000,‘xiaoli’,10);
1 row created.
SQL>

session 2:在父表上變更一條記錄,將會被掛起

SQL> select userenv('sid') from dual;
USERENV('SID')--------------
           191
SQL> update dept set deptno=10,dname='AAAAA' where deptno=10;

查詢鎖情況:

select
    mm.addr
  , mm.kaddr
  , mm.sid
  , row_number() over (partition by mm.type,mm.id1,mm.id2 order by mm.lmode desc ,mm.ctime desc) resource_row_number
  , mm.type
  , mm.id1
  , mm.id2
  , decode(mm.lmode, 0, null, 1, 'N', 2, 'SS|RS', 3, 'SX|RX', 4, 'S', 5, 'SSX|SRX', 6, 'X') lmode
  , decode(mm.request, 0, null, 1, 'N', 2, 'SS|RS', 3, 'SX|RX', 4, 'S', 5, 'SSX|SRX', 6, 'X') request--  , mm.ctime
  , lpad(trunc(mm.ctime/60/60),3) || ' Hour '
    || lpad(to_char(trunc(mm.ctime/60) - trunc(mm.ctime/60/60) * 60,'fm09'), 2) || ' Min '
    || lpad(to_char(mm.ctime - trunc(mm.ctime/60)*60,'fm09'), 2) || ' Sec' ctime
  , case when mm.block = 1 and mm.lmode != 0 then 'holder'
         when mm.block = 0 and mm.request != 0 then 'waiter'
         else null end role
  , case when ee.blocking_session is not null then 'waiting for SID '|| ee.blocking_session else null end blocking_session
  , dd.sql_text sql_text
  , cc.event wait_eventfrom
    v$lock mm
  , v$session ee
  , v$sqlarea dd
  , v$session_wait ccwhere mm.sid in (                select nn.sid                from (                  select
                      tt.*
                    , count(1) over (partition by  tt.type,tt.id1,tt.id2) cnt
                    , max(tt.lmode) over (partition by tt.type,tt.id1,tt.id2) lmod_flag
                    , max(tt.request) over (partition by tt.type,tt.id1,tt.id2) request_flag                  from v$lock tt ) nn                where nn.cnt > 1
                  and nn.lmod_flag != 0
                  and nn.request_flag != 0)  and mm.sid = ee.sid(+)  and ee.sql_id = dd.sql_id(+)  and mm.sid = cc.sid(+)order by mm.type, mm.id1, mm.id2,mm.lmode desc ,mm.ctime desc;

外鍵上有無索引的影響

這里我們可以看到:
session 1 正在做DML處理,對于DML處理會在表級鎖?上加上SX模式的鎖。
session 2 在更新主鍵deptno的時候,因為在子表EMP對應的外鍵字段上沒有鎖,因此需要在表級(TM)追加了一個S模式的鎖。
session 2 請求追加S模式的鎖在了TM上,因為SX與S模式的鎖是互斥的,因此session 2 被阻塞而掛起。

session 3:在子表上插入一條記錄,同樣將會被掛起

SQL> select userenv('sid') from dual;
USERENV('SID')--------------
           213
SQL> insert into emp values(3001,'xiaozhang',20);

查詢鎖情況:

select
    mm.addr
  , mm.kaddr
  , mm.sid
  , row_number() over (partition by mm.type,mm.id1,mm.id2 order by mm.lmode desc ,mm.ctime desc) resource_row_number
  , mm.type
  , mm.id1
  , mm.id2
  , decode(mm.lmode, 0, null, 1, 'N', 2, 'SS|RS', 3, 'SX|RX', 4, 'S', 5, 'SSX|SRX', 6, 'X') lmode
  , decode(mm.request, 0, null, 1, 'N', 2, 'SS|RS', 3, 'SX|RX', 4, 'S', 5, 'SSX|SRX', 6, 'X') request--  , mm.ctime
  , lpad(trunc(mm.ctime/60/60),3) || ' Hour '
    || lpad(to_char(trunc(mm.ctime/60) - trunc(mm.ctime/60/60) * 60,'fm09'), 2) || ' Min '
    || lpad(to_char(mm.ctime - trunc(mm.ctime/60)*60,'fm09'), 2) || ' Sec' ctime
  , case when mm.block = 1 and mm.lmode != 0 then 'holder'
         when mm.block = 0 and mm.request != 0 then 'waiter'
         else null end role
  , case when ee.blocking_session is not null then 'waiting for SID '|| ee.blocking_session else null end blocking_session
  , dd.sql_text sql_text
  , cc.event wait_eventfrom
    v$lock mm
  , v$session ee
  , v$sqlarea dd
  , v$session_wait ccwhere mm.sid in (                select nn.sid                from (                  select
                      tt.*
                    , count(1) over (partition by  tt.type,tt.id1,tt.id2) cnt
                    , max(tt.lmode) over (partition by tt.type,tt.id1,tt.id2) lmod_flag
                    , max(tt.request) over (partition by tt.type,tt.id1,tt.id2) request_flag                  from v$lock tt ) nn                where nn.cnt > 1
                  and nn.lmod_flag != 0
                  and nn.request_flag != 0)  and mm.sid = ee.sid(+)  and ee.sql_id = dd.sql_id(+)  and mm.sid = cc.sid(+)order by mm.type, mm.id1, mm.id2,mm.lmode desc ,mm.ctime desc;

外鍵上有無索引的影響

這里我們可以看到:
session 3 需要做DML處理,同樣需要請求SX模式的鎖在TM上,因此它被session 2 在TM上S模式鎖的請求阻塞。

三、模擬測試–外鍵有索引

session 1:

SQL> insert into emp values(3000,'xiaoli',10);
1 row created.
SQL>

session 2:

SQL> update dept set deptno=10,dname='AAAAA' where deptno=10;
1 row updated.
SQL>

這里發現session 2 就沒有被 session 1 所阻塞。

四、結論

1、所有的外鍵上創建索引,避免不必要的死鎖產生。
2、update 父表的語句,盡量避免更新主鍵。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泽库县| 香港| 梁河县| 金乡县| 手游| 怀安县| 高青县| 中山市| 新津县| 从化市| 阿拉善盟| 乡宁县| 白河县| 浠水县| 青岛市| 静乐县| 荥经县| 新余市| 泸州市| 建昌县| 盐源县| 肥西县| 天柱县| 吴桥县| 凤凰县| 祁连县| 金山区| 慈溪市| 九江市| 威远县| 昭觉县| 刚察县| 永善县| 宜城市| 舟山市| 宁德市| 开原市| 同仁县| 普兰店市| 酒泉市| 浠水县|