风哥教程参考DB2官方文档Index Management、Performance等内容,详细介绍索引维护、索引重组、索引优化等。更多视频教程www.fgedu.net.cn
目录大纲
Part01-索引维护概述
1.1 索引维护必要性
索引维护必要性:
- 提高查询性能
- 减少碎片
- 回收空间
- 更新统计信息
1.2 维护类型
- 重组索引:重建索引结构
- 更新统计信息:RUNSTATS
- 删除无用索引:清理冗余索引
- 重建索引:删除并重新创建
Part02-索引重组
2.1 索引重组方法
REORG INDEXES ALL FOR TABLE ORDERS;
# 重组指定索引
REORG INDEX IDX_ORDERS_CUSTOMER FOR TABLE ORDERS;
# 在线索引重组
REORG INDEXES ALL FOR TABLE ORDERS ALLOW WRITE ACCESS;
# 查看重组进度
SELECT
TABNAME,
INDNAME,
REORG_PHASE,
REORG_STATUS,
REORG_COMPLETION
FROM SYSIBMADM.SNAPREORG;
# 查看索引碎片
SELECT
INDNAME,
TABNAME,
NLEAF,
NLEVELS,
CLUSTERRATIO,
CLUSTERFACTOR
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’
ORDER BY CLUSTERRATIO ASC;
2.2 索引重建
DROP INDEX IDX_ORDERS_CUSTOMER;
# 重新创建索引
CREATE INDEX IDX_ORDERS_CUSTOMER ON ORDERS(CUSTOMER_ID, CREATE_TIME DESC);
# 使用REPLACE重建
CREATE OR REPLACE INDEX IDX_ORDERS_CUSTOMER ON ORDERS(CUSTOMER_ID);
# 批量重建索引
CREATE OR REPLACE PROCEDURE SP_REBUILD_INDEXES(
IN p_table_name VARCHAR(100)
)
LANGUAGE SQL
BEGIN
DECLARE v_indname VARCHAR(100);
DECLARE v_colnames VARCHAR(500);
DECLARE v_sql VARCHAR(1000);
FOR idx AS cur CURSOR FOR
SELECT INDNAME, COLNAMES
FROM SYSCAT.INDEXES
WHERE TABNAME = UPPER(p_table_name)
AND TABSCHEMA = ‘FGEDB’
AND INDNAME NOT LIKE ‘SQL%’
DO
SET v_indname = idx.INDNAME;
SET v_colnames = idx.COLNAMES;
SET v_sql = ‘DROP INDEX ‘ || v_indname;
EXECUTE IMMEDIATE v_sql;
SET v_sql = ‘CREATE INDEX ‘ || v_indname || ‘ ON ‘ || p_table_name || v_colnames;
EXECUTE IMMEDIATE v_sql;
END FOR;
END;
Part03-索引优化
3.1 索引设计优化
CREATE INDEX IDX_ORDERS_CUSTOMER_DATE ON ORDERS(CUSTOMER_ID, CREATE_TIME DESC);
# 创建包含列索引
CREATE INDEX IDX_ORDERS_COVER ON ORDERS(CUSTOMER_ID)
INCLUDE (TOTAL_AMOUNT, ORDER_STATUS);
# 创建分区索引
CREATE INDEX IDX_ORDERS_PART ON ORDERS(CREATE_TIME, ORDER_ID)
PARTITIONED;
# 创建MDC索引
CREATE INDEX IDX_ORDERS_MDC ON ORDERS(CREATE_DATE, REGION);
# 查看索引使用情况
SELECT
INDNAME,
TABNAME,
COLNAMES,
INDEXTYPE,
CARD,
FULLKEYCARD
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’;
# 查看索引大小
SELECT
INDNAME,
TABNAME,
NLEAF * 8 / 1024 AS SIZE_MB
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’
ORDER BY NLEAF DESC;
3.2 索引清理
SELECT
INDNAME,
TABNAME,
LAST_USED
FROM SYSCAT.INDEXES
WHERE LAST_USED < CURRENT DATE - 30 DAYS AND INDNAME NOT LIKE 'SQL%' ORDER BY LAST_USED; # 查找重复索引 SELECT TABNAME, COLNAMES, COUNT(*) AS INDEX_COUNT FROM SYSCAT.INDEXES WHERE TABSCHEMA = 'FGEDB' GROUP BY TABNAME, COLNAMES HAVING COUNT(*) > 1;
# 删除冗余索引
DROP INDEX IDX_ORDERS_CUSTOMER_OLD;
# 查找主键和外键
SELECT
CONSTNAME,
TABNAME,
COLNAMES
FROM SYSCAT.KEYCOLS
WHERE TABSCHEMA = ‘FGEDB’;
# 禁用索引(临时)
ALTER INDEX IDX_ORDERS_CUSTOMER DISABLE;
# 启用索引
ALTER INDEX IDX_ORDERS_CUSTOMER ENABLE;
Part04-索引监控
4.1 索引统计信息
RUNSTATS ON TABLE ORDERS FOR INDEX ALL;
# 更新指定索引统计信息
RUNSTATS ON TABLE ORDERS FOR INDEX IDX_ORDERS_CUSTOMER;
# 查看索引统计信息
SELECT
INDNAME,
TABNAME,
CARD,
FULLKEYCARD,
CLUSTERRATIO,
CLUSTERFACTOR,
SEQUENTIAL_PAGES,
DENSITY
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’;
# 查看索引基数
SELECT
INDNAME,
TABNAME,
FIRST2KEYCARD,
FIRST3KEYCARD,
FIRST4KEYCARD,
FULLKEYCARD
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’;
# 监控索引性能
SELECT
SUBSTR(INDNAME, 1, 30) AS INDNAME,
TABNAME,
INDEX_SCANS,
INDEX_ONLY_SCANS,
KEY_UPDATES,
PAGE_REORGS
FROM SYSIBMADM.INDEXMETRICS
ORDER BY INDEX_SCANS DESC;
4.2 索引健康检查
SELECT
INDNAME,
TABNAME,
CLUSTERRATIO,
CASE
WHEN CLUSTERRATIO < 0.8 THEN 'HIGH FRAGMENTATION' WHEN CLUSTERRATIO < 0.9 THEN 'MODERATE FRAGMENTATION' ELSE 'GOOD' END AS FRAGMENTATION_LEVEL FROM SYSCAT.INDEXES WHERE TABSCHEMA = 'FGEDB' ORDER BY CLUSTERRATIO ASC; # 检查索引层级 SELECT INDNAME, TABNAME, NLEVELS, CASE WHEN NLEVELS > 5 THEN ‘TOO MANY LEVELS’
ELSE ‘OK’
END AS LEVEL_STATUS
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’
ORDER BY NLEVELS DESC;
# 检查索引大小
SELECT
INDNAME,
TABNAME,
NLEAF * 8 / 1024 AS SIZE_MB,
CASE
WHEN NLEAF * 8 / 1024 > 1000 THEN ‘LARGE INDEX’
ELSE ‘OK’
END AS SIZE_STATUS
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’
ORDER BY NLEAF DESC;
# 创建索引健康报告
CREATE OR REPLACE PROCEDURE SP_INDEX_HEALTH_REPORT()
LANGUAGE SQL
BEGIN
INSERT INTO INDEX_HEALTH_REPORT (
REPORT_TIME, INDNAME, TABNAME, CLUSTERRATIO, NLEVELS, SIZE_MB, STATUS
)
SELECT
CURRENT TIMESTAMP,
INDNAME,
TABNAME,
CLUSTERRATIO,
NLEVELS,
NLEAF * 8 / 1024,
CASE
WHEN CLUSTERRATIO < 0.8 THEN 'NEEDS REORG'
WHEN NLEVELS > 5 THEN ‘TOO MANY LEVELS’
WHEN NLEAF * 8 / 1024 > 1000 THEN ‘LARGE INDEX’
ELSE ‘HEALTHY’
END
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = ‘FGEDB’;
END;
Part05-风哥经验总结与分享
5.1 索引维护要点
- 定期重组索引
- 定期更新统计信息
- 监控索引使用情况
- 清理无用索引
- 优化索引设计
- 建立索引监控机制
5.2 维护建议
| 维护类型 | 频率 | 执行时机 |
|---|---|---|
| 更新统计信息 | 每周 | 业务低峰期 |
| 索引重组 | 每月 | 业务低峰期 |
| 索引清理 | 每季度 | 业务低峰期 |
5.3 运维要点
- 监控索引碎片率
- 监控索引使用情况
- 定期执行RUNSTATS
- 定期重组索引
- 清理无用索引
- 建立索引维护计划
学习交流加群风哥微信: itpux-com
风哥Oracle/MySQL/PostgreSQL/Greenplum/DB2/Redis等数据库培训课程,10年一线实战经验,企业级培训,真正掌握数据库核心技术!
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
