Oracle 資料庫 19c 引入了自動索引功能,它可以讓您将一些有關索引管理的決策交給資料庫。
目錄
自動索引功能包括以下幾個特性:
- 可以根據資料表中列使用情況識别潛在的自動索引。 我們可以稱之為 “候選索引”。
- 将自動索引建立為不可見索引,是以它們不會在執行計劃中使用。 索引名稱包括“SYS_AI”字首。
- 針對 SQL 語句測試不可見的自動索引以確定它們能夠提升性能。 如果它們确實可以提高性能,就會變成可見索引。反之,如果性能沒有得到改善,相關的自動索引會被标記為不可用并随後被删除。 針對失敗的自動索引測試的 SQL 語句被列入阻止清單,是以将來不會考慮将它們用于自動索引。 優化器不會在第一次對資料庫運作 SQL 時考慮自動索引。
- 删除未使用的索引。
由于從未在 Exadata
上使用過此功能,是以無法評論其有效性。
此功能目前僅限于工程系統上的企業版,如此處所述。 有一種通過啟用
_exadata_feature_on
初始化參數進行測試的解決方案。
export ORACLE_SID=cdb1
export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES
sqlplus / as sysdba <<EOF
alter system set "_exadata_feature_on"=true scope=spfile;
shutdown immediate;
startup;
exit;
EOF
此方式不建議在生産系統進行使用,僅用于測試所用。
DBMS_AUTO_INDEX
包用于管理自動索引功能, 基本管理如下所述。
CDB_AUTO_INDEX_CONFIG
視圖顯示目前的自動索引配置,以下查詢使用
auto_index_config.sql腳本。
column parameter_name format a40
column parameter_value format a15
select con_id, parameter_name, parameter_value
from cdb_auto_index_config
order by 1, 2;
CON_ID PARAMETER_NAME PARAMETER_VALUE
---------- ---------------------------------------- ---------------
1 AUTO_INDEX_COMPRESSION OFF
1 AUTO_INDEX_DEFAULT_TABLESPACE
1 AUTO_INDEX_MODE OFF
1 AUTO_INDEX_REPORT_RETENTION 31
1 AUTO_INDEX_RETENTION_FOR_AUTO 373
1 AUTO_INDEX_RETENTION_FOR_MANUAL
1 AUTO_INDEX_SCHEMA
1 AUTO_INDEX_SPACE_BUDGET 50
3 AUTO_INDEX_COMPRESSION OFF
3 AUTO_INDEX_DEFAULT_TABLESPACE
3 AUTO_INDEX_MODE OFF
3 AUTO_INDEX_REPORT_RETENTION 31
3 AUTO_INDEX_RETENTION_FOR_AUTO 373
3 AUTO_INDEX_RETENTION_FOR_MANUAL
3 AUTO_INDEX_SCHEMA
3 AUTO_INDEX_SPACE_BUDGET 50
SQL>
如果我們切換到使用者定義的可插拔資料庫,我們就隻能檢視該容器的值。
alter session set container = pdb1;
SQL> @auto_index_config.sql
CON_ID PARAMETER_NAME PARAMETER_VALUE
---------- ---------------------------------------- ---------------
3 AUTO_INDEX_COMPRESSION OFF
3 AUTO_INDEX_DEFAULT_TABLESPACE
3 AUTO_INDEX_MODE OFF
3 AUTO_INDEX_REPORT_RETENTION 31
3 AUTO_INDEX_RETENTION_FOR_AUTO 373
3 AUTO_INDEX_RETENTION_FOR_MANUAL
3 AUTO_INDEX_SCHEMA
3 AUTO_INDEX_SPACE_BUDGET 50
SQL>
關于該參數的較長的描述可參考官方文檔: DBMS_AUTO_INDEX !
我們可以使用
DBMS_AUTO_INDEX
包的
CONFIGURE
過程配置來自動索引。
自動索引 的開關是使用
AUTO_INDEX_MODE
屬性控制的,該屬性具有以下幾種模式:
- IMPLEMENT:打開自動索引,提高性能的新索引變得可見并可供優化器使用。
- REPORT ONLY:打開自動索引,但新索引仍然不可見。
- OFF: 關閉自動索引。
可以使用以下指令進行模式間的切換:
exec dbms_auto_index.configure('AUTO_INDEX_MODE','IMPLEMENT');
exec dbms_auto_index.configure('AUTO_INDEX_MODE','REPORT ONLY');
exec dbms_auto_index.configure('AUTO_INDEX_MODE','OFF');
預設情況下,在預設永久表空間中建立自動索引。 如果想使用新的表空間來建立,可以使用
AUTO_INDEX_DEFAULT_TABLESPACE
屬性指定一個表空間來儲存它們。 下面我們建立一個表空間來儲存自動索引,并相應地設定屬性。
alter session set container = pdb1;
create tablespace auto_indexes_ts datafile size 100m autoextend on next 100m;
exec dbms_auto_index.configure('AUTO_INDEX_DEFAULT_TABLESPACE','AUTO_INDEXES_TS');
設定為
NULL
則代表使用預設的永久表空間:
Exec dbms_auto_index.configure('AUTO_INDEX_DEFAULT_TABLESPACE',NULL);
啟用自動索引後,在嘗試識别候選索引時會考慮所有使用者。 您可以使用
AUTO_INDEX_SCHEMA
屬性更改預設行為,這允許您維護包含/排除清單。
如果
ALLOW
參數設定為
TRUE
,則将指定的使用者添加到包含清單中。 請注意,它建構了一個包含使用者的謂詞。
exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', 'TEST', allow => TRUE);
exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', 'TEST2', allow => TRUE);
SQL> @auto_index_config.sql
CON_ID PARAMETER_NAME PARAMETER_VALUE
---------- ---------------------------------------- ----------------------------------------
3 AUTO_INDEX_COMPRESSION OFF
3 AUTO_INDEX_DEFAULT_TABLESPACE AUTO_INDEXES_TS
3 AUTO_INDEX_MODE IMPLEMENT
3 AUTO_INDEX_REPORT_RETENTION 31
3 AUTO_INDEX_RETENTION_FOR_AUTO 373
3 AUTO_INDEX_RETENTION_FOR_MANUAL
3 AUTO_INDEX_SCHEMA schema IN (TEST, TEST2)
3 AUTO_INDEX_SPACE_BUDGET 50
SQL>
可以使用
NULL
參數值将包含清單清空:
exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', NULL, allow => TRUE);
SQL> @auto_index_config.sql
CON_ID PARAMETER_NAME PARAMETER_VALUE
---------- ---------------------------------------- ----------------------------------------
3 AUTO_INDEX_COMPRESSION OFF
3 AUTO_INDEX_DEFAULT_TABLESPACE AUTO_INDEXES_TS
3 AUTO_INDEX_MODE IMPLEMENT
3 AUTO_INDEX_REPORT_RETENTION 31
3 AUTO_INDEX_RETENTION_FOR_AUTO 373
3 AUTO_INDEX_RETENTION_FOR_MANUAL
3 AUTO_INDEX_SCHEMA
3 AUTO_INDEX_SPACE_BUDGET 50
SQL>
ALLOW
FALSE
,則将指定的使用者添加到排除清單中:
exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', 'TEST', allow => FALSE);
exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', 'TEST2', allow => FALSE);
SQL> @auto_index_config.sql
CON_ID PARAMETER_NAME PARAMETER_VALUE
---------- ---------------------------------------- ----------------------------------------
3 AUTO_INDEX_COMPRESSION OFF
3 AUTO_INDEX_DEFAULT_TABLESPACE AUTO_INDEXES_TS
3 AUTO_INDEX_MODE IMPLEMENT
3 AUTO_INDEX_REPORT_RETENTION 31
3 AUTO_INDEX_RETENTION_FOR_AUTO 373
3 AUTO_INDEX_RETENTION_FOR_MANUAL
3 AUTO_INDEX_SCHEMA schema NOT IN (TEST, TEST2)
3 AUTO_INDEX_SPACE_BUDGET 50
SQL>
同樣的,可以使用
NULL
參數值将排除清單清空:
exec dbms_auto_index.configure('AUTO_INDEX_SCHEMA', NULL, allow => FALSE);
SQL> @auto_index_config.sql
CON_ID PARAMETER_NAME PARAMETER_VALUE
---------- ---------------------------------------- ----------------------------------------
3 AUTO_INDEX_COMPRESSION OFF
3 AUTO_INDEX_DEFAULT_TABLESPACE AUTO_INDEXES_TS
3 AUTO_INDEX_MODE IMPLEMENT
3 AUTO_INDEX_REPORT_RETENTION 31
3 AUTO_INDEX_RETENTION_FOR_AUTO 373
3 AUTO_INDEX_RETENTION_FOR_MANUAL
3 AUTO_INDEX_SCHEMA
3 AUTO_INDEX_SPACE_BUDGET 50
SQL>
如果需要了解其他參數,下面詳細說明了這些參數:
- AUTO_INDEX_COMPRESSION :文檔中未說明,大概用于控制壓縮級别, 預設
OFF
- AUTO_INDEX_REPORT_RETENTION :自動索引日志的保留期。 報告基于這些日志,預設
天。31
- AUTO_INDEX_RETENTION_FOR_AUTO :未使用的自動索引的保留期,預設
373
- AUTO_INDEX_RETENTION_FOR_MANUAL :未使用的手動建立索引的保留期,當設定為
時,不考慮删除手動建立的索引,預設為空。NULL
- AUTO_INDEX_SPACE_BUDGET :用于自動索引存儲的預設永久表空間的百分比,使用 AUTO_INDEX_DEFAULT_TABLESPACE 參數指定自定義表空間時,将忽略此參數。
‼️ 做這個之前要仔細考慮,測試,測試,測試!
如果你真的勇氣非凡,
DROP_SECONDARY_INDEXES
過程将删除除用于限制的索引之外的所有索引。 這可以在表、模式或資料庫級别完成。
-- Table-level
exec dbms_auto_index.drop_secondary_indexes('MY_SCHEMA', 'MY_TABLE');
-- Schema-level
exec dbms_auto_index.drop_secondary_indexes('MY_SCHEMA');
-- Database-level
exec dbms_auto_index.drop_secondary_indexes;
這讓您一清二楚,是以自動索引可以為您做出所有索引決策。
DROP_AUTO_INDEXES
過程允許我們删除自動建立的索引。根據參數值,我們可以删除指定的自動索引,也可以是使用者的所有自動索引。
删除指定的自動索引,并確定它不會被重新建立。 請注意,索引名稱是
雙引号
的!
begin
dbms_auto_index.drop_auto_indexes(
owner => 'MY_SCHEMA',
index_name => '"SYS_AI_512bd3h5nif1a"',
allow_recreate => false);
end;
/
删除指定使用者下的所有自動索引,但允許重新建立它們:
begin
dbms_auto_index.drop_auto_indexes(
owner => 'MY_SCHEMA',
index_name => null,
allow_recreate => true);
end;
/
删除目前使用者的所有自動索引,但允許重新建立它們:
begin
dbms_auto_index.drop_auto_indexes(
owner => null,
index_name => null,
allow_recreate => true);
end;
/
在此功能的初始版本中,沒有一種機制可以删除由自動索引功能建立的特定索引,或者首先阻止建立特定索引。
Franck Pachot
寫了一些可以讓你做到這一點的黑客。
有幾個與自動索引功能相關的視圖,如下所示:
select view_name
from dba_views
where view_name like 'DBA_AUTO_INDEX%'
order by 1;
VIEW_NAME
--------------------------------------------------------------------------------
DBA_AUTO_INDEX_CONFIG
DBA_AUTO_INDEX_EXECUTIONS
DBA_AUTO_INDEX_IND_ACTIONS
DBA_AUTO_INDEX_SQL_ACTIONS
DBA_AUTO_INDEX_STATISTICS
DBA_AUTO_INDEX_VERIFICATIONS
SQL>
此外,
{CDB|DBA|ALL|USER}_INDEXES
視圖包括
AUTO
列,該列訓示索引是否由自動索引功能建立。
以下查詢可以使用
auto_indexes.sql腳本:
column owner format a30
column index_name format a30
column table_owner format a30
column table_name format a30
select owner,
index_name,
index_type,
table_owner,
table_name
table_type
from dba_indexes
where auto = 'YES'
order by owner, index_name;
DBMS_AUTO_INDEX
包包含兩個報告函數:
DBMS_AUTO_INDEX.REPORT_ACTIVITY (
activity_start IN TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP - 1,
activity_end IN TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP,
type IN VARCHAR2 DEFAULT 'TEXT',
section IN VARCHAR2 DEFAULT 'ALL',
level IN VARCHAR2 DEFAULT 'TYPICAL')
RETURN CLOB;
DBMS_AUTO_INDEX.REPORT_LAST_ACTIVITY (
type IN VARCHAR2 DEFAULT 'TEXT',
section IN VARCHAR2 DEFAULT 'ALL',
level IN VARCHAR2 DEFAULT 'TYPICAL')
RETURN CLOB;
REPORT_ACTIVITY
函數允許您顯示指定時間段内的活動,預設為最後一天。
REPORT_LAST_ACTIVITY
函數報告最後一次自動索引操作。 兩者都允許您使用以下參數定制輸出。
- TYPE :允許的值(文本、HTML、XML)。
- SECTION:允許值(SUMMARY、INDEX_DETAILS、VERIFICATION_DETAILS、ERRORS、ALL)。 您還可以使用“+”和“-”字元的組合來訓示是否應該包括或排除某些内容。 例如“SUMMARY +ERRORS”或“ALL -ERRORS”。
- LEVEL :允許值(基本、典型、全部)。
下面顯示了從 SQL 中使用這些函數的一些示例。 注意 LEVEL 參數的引用。 在 SQL 調用中使用 this 時這是必需的,是以它了解這不是對 LEVEL 僞列的引用。
DBMS_AUTO_INDEX.REPORT_ACTIVITY (
activity_start IN TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP - 1,
activity_end IN TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP,
type IN VARCHAR2 DEFAULT 'TEXT',
section IN VARCHAR2 DEFAULT 'ALL',
level IN VARCHAR2 DEFAULT 'TYPICAL')
RETURN CLOB;
DBMS_AUTO_INDEX.REPORT_LAST_ACTIVITY (
type IN VARCHAR2 DEFAULT 'TEXT',
section IN VARCHAR2 DEFAULT 'ALL',
level IN VARCHAR2 DEFAULT 'TYPICAL')
RETURN CLOB;
以下是在建立任何索引之前預設活動報告的輸出示例:
select dbms_auto_index.report_activity() from dual;
GENERAL INFORMATION
-------------------------------------------------------------------------------
Activity start : 03-JUN-2019 21:59:21
Activity end : 04-JUN-2019 21:59:21
Executions completed : 2
Executions interrupted : 0
Executions with fatal error : 0
-------------------------------------------------------------------------------
SUMMARY (AUTO INDEXES)
-------------------------------------------------------------------------------
Index candidates : 0
Indexes created : 0
Space used : 0 B
Indexes dropped : 0
SQL statements verified : 0
SQL statements improved : 0
SQL plan baselines created : 0
Overall improvement factor : 0x
-------------------------------------------------------------------------------
SUMMARY (MANUAL INDEXES)
-------------------------------------------------------------------------------
Unused indexes : 0
Space used : 0 B
Unusable indexes : 0
-------------------------------------------------------------------------------
ERRORS
---------------------------------------------------------------------------------------------
No errors found.
---------------------------------------------------------------------------------------------
SQL>