全域性索引失效帶來的幾個測試場景
SQL> create table xue.test_pp(id number,name varchar2(10)) partition by range (id) (partition pa values less than (10),partition pb values less than (20),partition pc values less than (30));
Table created.
SQL> insert into xue.test_pp values (1,’a');
1 row created.
SQL> insert into xue.test_pp values (11,’aa’);
1 row created.
SQL> insert into xue.test_pp values (22,’bb’);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from xue.test_pp;
ID NAME
———- ———-
1 a
11 aa
22 bb
SQL> alter table xue.test_pp add constraint u_pp unique (id);
Table altered.
SQL> select index_name,status,partitioned from dba_indexes where table_name=’TEST_PP’;
U_PP VALID NO
普通DML不會導致索引失效:
SQL> insert into xue.test_pp values (23,’cc’);
1 row created.
SQL> commit;
Commit complete.
SQL> select index_name,status,partitioned from dba_indexes where table_name=’TEST_PP’;
U_PP VALID NO
SQL> update xue.test_pp set name=’bc’ where id=23;
1 row updated.
SQL> commit;
Commit complete.
SQL> select index_name,status,partitioned from dba_indexes where table_name=’TEST_PP’;
U_PP VALID NO
SQL> delete from xue.test_pp where id=23;
1 row deleted.
SQL> commit;
Commit complete.
SQL> select index_name,status,partitioned from dba_indexes where table_name=’TEST_PP’;
U_PP VALID NO
tuncate 一個分割槽則導致索引無效:
SQL> select * from xue.test_pp;
1 a
11 aa
22 bb
SQL> alter table xue.test_pp truncate partition pc;
Table truncated.
SQL> select * from xue.test_pp;
1 a
11 aa
SQL> select index_name,status,partitioned from dba_indexes where table_name=’TEST_PP’;
U_PP UNUSABLE NO
在這種情況下做INSERT/DELETE操作會報錯:
SQL> insert into xue.test_pp values(23,’dd’);
insert into xue.test_pp values(23,’dd’)
*
ERROR at line 1:
ORA-01502: index ‘XUE.U_PP’ or partition of such index is in unusable state
即使是插入到沒有TRUNCATE的分割槽也報錯:
SQL> insert into xue.test_pp values(12,’dd’);
insert into xue.test_pp values(12,’dd’)
*
ERROR at line 1:
ORA-01502: index ‘XUE.U_PP’ or partition of such index is in unusable state
–DELETE報錯:
SQL> delete from xue.test_pp where id=11;
delete from xue.test_pp where id=11
*
ERROR at line 1:
ORA-01502: index ‘XUE.U_PP’ or partition of such index is in unusable state
不過做UPDATE不會報錯:
SQL> update xue.test_pp set name=’bc’ where id=11;
1 row updated.
建立一個local索引:
SQL> create unique index xue.UUU on xue.test_pp(id) local;
create unique index xue.UUU on xue.test_pp(id) local
*
ERROR at line 1:
ORA-01408: such column list already indexed
SQL> create unique index xue.UUU on xue.test_pp(id,name) local;
Index created.
SQL> select index_name,status,partitioned from dba_indexes where table_name=’TEST_PP’;
UUU N/A YES
U_PP UNUSABLE NO
SQL> select index_name,status from dba_ind_partitions where INDEX_name=’UUU’;
UUU USABLE
UUU USABLE
UUU USABLE
在全域性索引、本地索引共存的情況下仍然報錯:
SQL> delete from xue.test_pp where id=11;
delete from xue.test_pp where id=11
*
ERROR at line 1:
ORA-01502: index ‘XUE.U_PP’ or partition of such index is in unusable state
刪除原來的索引後就不再報錯:
SQL> alter table xue.test_pp disable constraint u_pp;
Table altered.
SQL> delete from xue.test_pp where id=11;
1 row deleted.
在這種情況下,觀察語句的執行計劃:
update xue.test_pp set name=’cce’ where id=13;
select * from v$sqlarea where sql_text like ‘%test_pp%’
select * from table(dbms_xplan.display_cursor(‘12jr4j8vzx5pw’));
SQL_ID 12jr4j8vzx5pw, child number 0
————————————-
update xue.test_pp set name=’cce’ where id=13
Plan hash value: 935868745
—————————————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
—————————————————————————————————
| 0 | UPDATE STATEMENT | | | | 1 (100)| | | |
| 1 | UPDATE | TEST_PP | | | | | | |
| 2 | PARTITION RANGE SINGLE| | 1 | 20 | 1 (0)| 00:00:01 | 2 | 2 |
|* 3 | INDEX RANGE SCAN | UUU | 1 | 20 | 1 (0)| 00:00:01 | 2 | 2 |
—————————————————————————————————
Predicate Information (identified by operation id):
—————————————————
3 – access("ID"=13)
Note
—–
– dynamic sampling used for this statement
該操作使用了新索引:UUU,同時使用了INDEX RANGE SCAN
建立原來的索引:
SQL> alter table xue.test_pp enable constraint u_pp;
Table altered.
SQL> select index_name from dba_indexes where table_name=’TEST_PP’;
UUU
U_PP
這種情況下該語句的執行計劃變為:
SQL_ID 7crj9fgwu7kfw, child number 0
————————————-
update xue.test_pp set name=’eeee’ where id=13
Plan hash value: 2992425951
——————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
——————————————————————-
| 0 | UPDATE STATEMENT | | | | 1 (100)|
| 1 | UPDATE | TEST_PP | | | |
|* 2 | INDEX UNIQUE SCAN| U_PP | 1 | 20 | 0 (0)|
——————————————————————-
Predicate Information (identified by operation id):
—————————————————
2 – access("ID"=13)
可以看到,使用U_PP索引時是INDEX UNIQUE SCAN。
修改測試語句的where條件:
update xue.test_pp set name=’ffff’ where id=13 and name=’eeee’;
SQL_ID 8r665dj5174n0, child number 0
————————————-
update xue.test_pp set name=’ffff’ where id=13 and name=’eeee’
Plan hash value: 1843624919
—————————————————————————————-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Pstart| Pstop |
—————————————————————————————-
| 0 | UPDATE STATEMENT | | | | 1 (100)| | |
| 1 | UPDATE | TEST_PP | | | | | |
| 2 | PARTITION RANGE SINGLE| | 1 | 20 | 0 (0)| 2 | 2 |
|* 3 | INDEX UNIQUE SCAN | UUU | 1 | 20 | 0 (0)| 2 | 2 |
—————————————————————————————-
Predicate Information (identified by operation id):
—————————————————
3 – access("ID"=13 AND "NAME"=’eeee’)
–刪掉索引
SQL> drop index XUE.UUU
2 ;
Index dropped.
update xue.test_pp set name=’aaaaaa’ where id=13 and name=’ffff’;
Execution Plan
———————————————————-
Plan hash value: 714092732
—————————————————————————————————-
———–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Psta
rt| Pstop |
—————————————————————————————————-
———–
| 0 | UPDATE STATEMENT | | 1 | 6 | 1 (0)| 00:00:01 |
| |
| 1 | UPDATE | TEST_PP | | | | |
| |
|* 2 | TABLE ACCESS BY GLOBAL INDEX ROWID| TEST_PP | 1 | 6 | 1 (0)| 00:00:01 |
2 | 2 |
|* 3 | INDEX UNIQUE SCAN | U_PP | 1 | | 0 (0)| 00:00:01 |
| |
—————————————————————————————————-
———–
Predicate Information (identified by operation id):
—————————————————
2 – filter("NAME"=’ffff’)
3 – access("ID"=13)
–使用了索引U_PP,不過仍然是INDEX UNIQUE SCAN
測試結論
1、truncate 操作會導致全域性索引失效
2、如果全域性索引失效,即使有其他索引可用,該表也不能進行INSERT\DELETE,可以UPDATE。
3、假設有索引1(索引列為id1),索引2(索引列為id1,id2),且都是unique索引,則:
–只有索引2的情況下:
以id1為where條件的語句會使用索引2,但是其索引模式為:INDEX RANGE SCAN;
以id1,id2為where條件的語句會使用索引2,並且其索引模式為:INDEX UNIQUE SCAN ;
–只有索引1的情況下:
以id1為where條件,或以id1,id2為條件,都會使用索引1,並且其索引模式為:INDEX UNIQUE SCAN ;
–2個索引都存在的情況下:
以id1為where條件的語句會使用索引1,並且其索引模式為:INDEX UNIQUE SCAN ;
以id1,id2為where條件的語句會使用索引2,並且其索引模式為:INDEX UNIQUE SCAN ;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23732248/viewspace-2987152/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 索引失效場景索引
- MySQL系列:索引失效場景總結MySql索引
- phoenix全域性索引和本地索引 概述,使用場景,區別等詳解索引
- 8個Spring事務失效的場景,你碰到過幾種?Spring
- spring事務失效的幾種場景以及原因Spring
- 事務 - 失效的場景
- MySQL資料庫索引以及失效場景詳解DELNMySql資料庫索引
- 利用 OpenAI 的文字生成模型,自動生成測試用例的幾個場景示例OpenAI模型
- 面試官:你知道哪些事務失效的場景?面試
- 面試官:聊聊索引失效?失效的原因是什麼?面試索引
- 效能測試場景提取
- oracle交換分割槽所引起的索引失效問題探究測試Oracle索引
- 單元測試 - 測試場景記錄
- 我面試幾乎必問:你設計索引的原則是什麼?怎麼避免索引失效?面試索引
- 簡單介紹MySQL索引失效的幾種情況MySql索引
- go語言reflect包使用的幾個場景Go
- 移動App測試崩潰常見的測試場景APP
- 《安全測試常用的幾個工具》
- EF Core 索引器屬性(Indexer property)場景及應用索引Index
- 效能測試混合場景計算
- 求助,jmeter 壓測 ,業務場景測試JMeter
- Tessy—支援複雜場景測試的單元整合測試工具
- 幾個場景下用flink如何解決的思考
- @Transactional 註解下,事務失效的多種場景
- 一文詳解 OceanBase 2.0 的“全域性索引”功能索引
- 索引設計(組合索引適用場景)索引
- Apache Hudi重磅特性解讀之全域性索引Apache索引
- 【TcaplusDB知識庫】TcaplusDB全域性索引介紹索引
- API自動化測試平臺,支援場景化的API測試API
- Jmeter效能測試場景的建立和執行JMeter
- 帶屏智慧音響的全域性商戰,百度和阿里的勝算幾何?阿里
- mysql索引失效的情況MySql索引
- 探索MySQL的InnoDB索引失效MySql索引
- 基於似然場的全域性定位
- multi-key索引和wildCard索引場景比較索引
- 軟體效能測試的幾個階段
- CCE雲原生混部場景下的測試案例
- JMeter MQTT 在連線測試場景中的使用JMeterMQQT