在DM數據庫的日常使用中,本人通過各種途徑(數據庫安裝后的doc目錄、官方eco社區、互聯網,以及同事技術交流)收集了有一些高頻實用的SQL命令集,本文將悉數羅列出來,日后將繼續補充完善。
表結構查看
如何獲取表字段信息和列注釋信息?
-- 獲取表結構信息(包括注釋和是否自增列)
SELECT S.NAME AS 表名,
C.NAME AS 列名,
C.TYPE$ AS 類型,
C.LENGTH$ AS 長度,
C.SCALE AS 標度,
C.INFO2&1 AS 自增字段,
C.NULLABLE$ AS 可為空,
C.DEFVAL AS 默認值,
(SELECT COMMENTS
FROM ALL_COL_COMMENTS CC
WHERE CC.OWNER = SF_GET_SCHEMA_NAME_BY_ID(S.SCHID)
AND CC.TABLE_NAME = S.NAME
AND CC.COLUMN_NAME = C.NAME) AS 列注釋
FROM SYSOBJECTS S,
SYSCOLUMNS C
WHERE S.ID = C.ID
-- 默認查詢當前用戶下面的用戶表,要查看其他模式的表,請替換下面的USER函數為指定的模式名
-- AND S.SCHID = SF_GET_SCHEMA_ID_BY_NAME(USER)
AND SUBTYPE$ = 'UTAB'
-- 默認查詢指定模式下所有的表,取消下方注釋,替換表名DEPT為你需要查看的表名
AND S.NAME = 'USERINFO'
ORDER BY S.NAME, C.COLID;
如何獲取數據庫對象(表、索引、函數、過程)的DDL語句?
-- 根據表名返回DDL語句
SELECT TABLEDEF(USERNAME=>'TEST',TABLENAME=>'DICT_AREA');
-- 根據對象類型、對象名、對象所屬模式返回DDL語句
SELECT SF_DBMS_METADATA_GET_DDL(OBJECT_TYPE=>'TABLE',OBJECT_NAME=>'DICT_AREA',SCHNAME=>'TEST');
系統函數信息
如何獲知某個函數、過程所需的參數有哪些?
-- 模糊搜索函數名
SELECT * FROM V$IFUN WHERE NAME LIKE upper('%table_used_space%');
-- 根據上一步id查詢函數參數
SELECT * FROM V$IFUN_ARG WHERE id= V$IFUN.ID ;
用戶與模式對應
如何獲取用戶與模式的對應關系?如果找到哪些用戶擁有多個模式?
-- 獲取用戶與模式的對應映射關系
SELECT SF_GET_USERNAME_BY_ID(PID) AS USERNAME,
LISTAGG(NAME, ',') WITHIN GROUP (ORDER BY CRTDATE) AS SCHEMA_NAME
FROM SYSOBJECTS
WHERE TYPE$ = 'SCH'
GROUP BY SF_GET_USERNAME_BY_ID(PID)
ORDER BY USERNAME;
空間占用
表空間占用情況
哪些表空間空間所剩不多,需要提前擴充?哪些表空間使用率較低?(在磁盤緊張的時候考慮充分利用起來)
-- 查看表空間占用
SELECT D.TABLESPACE_NAME "Name",
--d.contents "Type",
TO_CHAR(NVL(A.BYTES / 1024 / 1024 / 1024, 0), '99999999.9') "總空間(GB)",
TO_CHAR(NVL(A.BYTES2 / 1024 / 1024 / 1024, 0), '99999999.9') "已使用(GB)",
TO_CHAR(NVL((A.BYTES2 / A.BYTES * 100), 0), '990.99') "使用%",
TO_CHAR(NVL((A.BYTES2 - NVL(F.BYTES, 0)) / A.BYTES2 * 100, 0), '990.99') "使用率%"
FROM SYS.DBA_TABLESPACES D,
(
SELECT TABLESPACE_NAME,
SUM(GREATEST(BYTES, MAXBYTES)) BYTES,
SUM(BYTES) BYTES2
FROM DBA_DATA_FILES
GROUP BY TABLESPACE_NAME
) A,
(
SELECT TABLESPACE_NAME,
SUM(BYTES) BYTES
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME
) F
WHERE D.TABLESPACE_NAME = A.TABLESPACE_NAME(+)
AND D.TABLESPACE_NAME = F.TABLESPACE_NAME(+)
ORDER BY NVL((A.BYTES2 - NVL(F.BYTES, 0)) / A.BYTES2 * 100, 0) DESC;
用戶表占用情況
某個用戶模式下來的表都占用了多大空間,分別有多少行?大表有哪些?
-- 通過頁數和顯示單位(可選參數MB/GB,默認KB為單位顯示)
WITH FUNCTION GET_SIZE_BY_PAGES(NUM_OF_PAGE INT, KB_MB_GB VARCHAR(2) DEFAULT 'KB') RETURN NUMBER(15, 2) AS
V_SIZE_KB NUMBER(15, 2) := ROUND(PAGE() * NUM_OF_PAGE / 1024.00, 2);
BEGIN
IF KB_MB_GB = 'MB' THEN
RETURN V_SIZE_KB / 1024.00;
ELSIF KB_MB_GB = 'GB' THEN
RETURN V_SIZE_KB / 1024.00 / 1024.00;
END IF;
RETURN V_SIZE_KB;
END;
-- 查看每個表空間占用情況和行數
SELECT T.TABLESPACE_NAME,
T.OWNER,
T.TABLE_NAME,
GET_SIZE_BY_PAGES(TABLE_USED_PAGES(T.OWNER, T.TABLE_NAME), 'MB') AS TABLE_USED_SPACE_MB,
GET_SIZE_BY_PAGES(TABLE_USED_PAGES(T.OWNER, T.TABLE_NAME), 'GB') AS TABLE_USED_SPACE_GB,
TABLE_ROWCOUNT(T.OWNER, T.TABLE_NAME) AS TABLE_ROWCOUNT
FROM DBA_TABLES T
WHERE T.OWNER IN ('TEST')
ORDER BY TABLE_USED_SPACE_MB DESC, TABLE_ROWCOUNT DESC;
性能診斷
阻塞會話SQL
當前哪個會話正在執行的哪條SQL(持有的鎖)阻塞了另外哪個會話的哪一個SQL正在等待執行?
-- 查詢持有鎖的會話和等待鎖的會話V$TRXWAIT版本
SELECT H.SESS_ID AS HOLD_LOCK_SESSION_ID,
CONCAT('SP_CLOSE_SESSION(', H.SESS_ID, ');') AS HOLD_LOCK_SESSION_KILL,
H.SQL_TEXT AS HOLD_LOCK_SESSION_SQL,
H.STATE AS HOLD_LOCK_SESSION_STATE,
H.CLNT_HOST AS HOLD_LOCK_CLIENT_HOST,
H.CLNT_IP AS HOLD_LOCK_CLIENT_IP,
H.THRD_ID AS HOLD_LOCK_THRD,
H.TRX_ID AS HOLD_LOCK_TRX_ID,
T.WAIT_TIME / 1000.00 AS WAIT_SECOND,
W.*
FROM SYS."V$TRXWAIT" T
JOIN SYS."V$SESSIONS" H ON T.WAIT_FOR_ID = H.TRX_ID
JOIN SYS."V$SESSIONS" W ON T.ID = W.TRX_ID
WHERE H.STATE != 'ACTIVE'
ORDER BY WAIT_SECOND DESC;
-- 或者使用以下查詢方式
-- 查詢持有鎖的會話和等待鎖的會話
SELECT H.SESS_ID AS HOLD_LOCK_SESSION_ID,
CONCAT('SP_CLOSE_SESSION(', H.SESS_ID, ');') AS HOLD_LOCK_SESSION_KILL,
TO_CHAR(H.SQL_TEXT) AS HOLD_LOCK_SESSION_SQL,
H.STATE AS HOLD_LOCK_SESSION_STATE,
H.CLNT_HOST AS HOLD_LOCK_CLIENT_HOST,
H.CLNT_IP AS HOLD_LOCK_CLIENT_IP,
H.THRD_ID AS HOLD_LOCK_THRD,
H.TRX_ID AS HOLD_LOCK_TRX_ID,
SF_GET_TABLENAME_BY_ID(L.TABLE_ID) AS LOCKED_TABLE,
CONCAT('SP_CLOSE_SESSION(', W.SESS_ID, ');') AS WAITING_SESSION_KILL,
W.*
FROM SYS."V$LOCK" L
JOIN SYS."V$SESSIONS" W ON L.TRX_ID = W.TRX_ID AND L.BLOCKED = 1
JOIN SYS."V$SESSIONS" H ON L.TID = H.TRX_ID;
--WHERE H.STATE != 'ACTIVE';
使用大量內存的SQL
哪些SQL占用了大量的內存?
-- 查詢最近1000條內存占用量高的SQL
select * from SYS."V$LARGE_MEM_SQLS" ORDER BY FINISH_TIME DESC;
-- 查詢系統中內存占用量最高的20條SQL
SELECT *
FROM V$SYSTEM_LARGE_MEM_SQLS
ORDER BY "V$SYSTEM_LARGE_MEM_SQLS".MEM_USED_BY_K DESC;
-- 查詢最近內存占用最高的10000條SQL
SELECT SF_GET_SESSION_SQL(SESSID),
MAX_MEM_USED / 1024.0 MAX_MEM_USED_MB,
SQL_TXT
FROM V$SQL_STAT_HISTORY
ORDER BY MAX_MEM_USED DESC;
慢查詢定位
如何快速的獲取慢查詢語句?
-- 查詢執行時間大於2秒的活動會話
SELECT SESS_ID,
SQL_TEXT,
DATEDIFF(SS, LAST_RECV_TIME, SYSDATE) EXETIME,
TO_CHAR(SF_GET_SESSION_SQL(SESSID)) FULLSQL,
CLNT_IP
FROM V$SESSIONS
WHERE STATE = 'ACTIVE'
AND LAST_RECV_TIME <= SYSDATE - 1 / 24 / 60 * 2;
-- 顯示系統最近 1000 條執行時間超過預定值(SF_GET_LONG_TIME,該閥值可通過SP_SET_LONG_TIME調整)的 SQL 語句
select * from SYS."V$LONG_EXEC_SQLS";
-- 顯示系統自啟動以來執行時間最長的 20 條 SQL 語句
select * from SYS."V$SYSTEM_LONG_EXEC_SQLS";
慢查詢分析
如何知道SQL執行計划的哪些執行步驟消耗最長,更值得優化?
-- 通過ET查看SQL各個執行階段耗時
SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC',1);
-- 下面執行需要測量的查詢,獲取執行號
select count(*) from AIRPORT.BOOKING;
-- 使用下面的存儲過程或者直接點擊管理工具消息窗口中的執行號超級鏈接
et(16974);
-- 取消監控
SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC',0);
備份集
-- 備份集查看
SELECT BACKUP_TIME,
BACKUP_NAME,
BACKUP_PATH,
CASE TYPE WHEN 1 THEN '增備' ELSE '全備' END AS "type"
FROM V$BACKUPSET
WHERE PARENT_ID = -1
ORDER BY BACKUP_TIME DESC;
系統信息
如何通過數據庫快速查看服務器的負載信息?
-- 系統信息
select * from SYS."V$SYSTEMINFO";
license授權信息
如何查看當前數據庫的授權信息?授權的的到期時間是什么時候?
-- 查看授權信息
SELECT SERIES_NO,
EXPIRED_DATE,
AUTHORIZED_CUSTOMER,
PROJECT_NAME,
CLUSTER_TYPE
FROM V$LICENSE;
替換授權的KEY之后,如何刷新授權信息?
-- 重新載入授權
CALL P_LOAD_LIC_INFO();
小技巧
這么多的常用SQL命令,大家都是保存到哪里的呢?保存后又是怎樣才能快速地找出來並調用?
好多同學可能會將這些日常使用的SQL用文本文件的方式,或者通過各種筆記軟件(有道雲筆記、印象筆記等等)進行記錄並保存,每次使用的時候再打開這個文本文件進行搜索、復制、粘貼。
這些方法都未嘗不可,但對於追求效率的我們來說,稍微有那么一點點的麻煩。我在這里推薦給大家一個我日常使用的小技巧:將日常使用頻繁的SQL命令添加的輸入法的自定義詞條,這樣不僅可能快速查找並調用,還能支持雲端同步保存。下面,我將以搜狗輸入法為例進行演示。
例如,大家很多時候想查看某些(個)表結構信息(字段名、字段類型、默認值、是否自增列、列注釋等),可能會通過DM管理工具依次點擊【對象導航】→【模式名】→【表名】→【修改】、【屬性】、【列】打開對應窗口進行查看。但如果使用輸入法的自定義詞條功能,那么通常只需要切換到搜索輸入法,然后鍵入desc,然后選擇5(假設我們將該SQL查詢命令候選項設置為5),即可快速調用查看表結構的SQL命令。如下圖所示:
達夢技術社區:https://eco.dameng.com/