From 5bc548be15a2e571ac4c4e6c0bcc09416b0ef814 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Wed, 10 Sep 2025 16:00:08 +0800 Subject: [PATCH 1/5] draft --- TOC.md | 1 + .../index-management-best-practices.md | 313 ++++++++++++++++++ 2 files changed, 314 insertions(+) create mode 100644 best-practices/index-management-best-practices.md diff --git a/TOC.md b/TOC.md index 1cef3e0e1f08..73ed10bf9ce7 100644 --- a/TOC.md +++ b/TOC.md @@ -428,6 +428,7 @@ - [TiDB 最佳实践](/best-practices/tidb-best-practices.md) - [DDL 最佳实践](/ddl-introduction.md) - [多列索引优化最佳实践](/best-practices/multi-column-index-best-practices.md) + - [理索引和识别未使用索引的最佳实践](/best-practices/index-management-best-practices.md) - [SaaS 多租户场景下处理百万张表](/best-practices/saas-best-practices.md) - [将 UUID 用作主键的最佳实践](/best-practices/uuid.md) - [Java 应用开发最佳实践](/best-practices/java-app-best-practices.md) diff --git a/best-practices/index-management-best-practices.md b/best-practices/index-management-best-practices.md new file mode 100644 index 000000000000..76de59757a0c --- /dev/null +++ b/best-practices/index-management-best-practices.md @@ -0,0 +1,313 @@ +--- +title: 管理索引和识别未使用索引的最佳实践 +summary: 了解在 TiDB 中管理和优化索引、识别并移除未使用索引的最佳实践。 +--- + +# 理索引和识别未使用索引的最佳实践 + +索引对于优化数据库查询性能至关重要,可以减少全表扫描的数据量。然而,随着应用演进、业务逻辑变化和数据量增长,索引也会出现效率问题,包括: + +- 未使用索引:这些索引曾经有用,但现在查询优化器已不再选择它们,导致占用存储空间并增加写入操作的额外开销。 +- 低效索引:某些索引虽然被优化器使用,但扫描的数据量远超预期,增加磁盘 I/O 并拖慢查询速度。 + +如果不及时处理,索引问题会导致存储成本上升、性能下降和运维效率降低。在 TiDB 这样的分布式 SQL 数据库中,索引效率问题影响更大,因为分布式查询和多节点协作更为复杂。因此,定期进行索引审计对于保持数据库优化至关重要。 + +主动识别和优化索引有助于: + +- 降低存储开销:移除未使用索引可释放磁盘空间,降低长期存储成本。 +- 提升写入性能:写密集型场景(如 `INSERT`、`UPDATE`、`DELETE`)在减少不必要索引维护后性能更佳。 +- 优化查询执行:高效索引减少扫描行数,加快查询速度和响应时间。 +- 简化数据库管理:索引更少且优化后,备份、恢复和结构变更更简单。 + +由于索引会随业务逻辑变化而演进,定期索引审计是数据库维护的标准流程。TiDB 提供内置可观测性工具,帮助你安全高效地检测、评估和优化索引。 + +TiDB v8.0.0 引入了 [`INFORMATION_SCHEMA.TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) 表和 [`sys.schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 视图,帮助你追踪索引使用模式,做出数据驱动的决策。 + +本文介绍如何利用这些工具检测并移除未使用或低效索引,从而提升 TiDB 性能与稳定性。 + +## TiDB 索引优化:数据驱动的方法 + +索引对查询性能至关重要,但如果没有充分分析就移除,可能导致性能回退甚至系统不稳定。为确保索引管理的安全与有效,TiDB 提供内置可观测性工具,支持以下操作: + +- 实时追踪索引使用:识别索引访问频率及其对性能的贡献。 +- 检测未使用索引:定位自上次数据库重启后未被使用的索引。 +- 评估索引效率:判断索引是否有效过滤数据,或带来过多 I/O 开销。 +- 安全测试索引移除:可先将索引设为不可见,确保无查询依赖后再删除。 + +TiDB 通过以下强大工具简化索引优化: + +- `INFORMATION_SCHEMA.TIDB_INDEX_USAGE`:监控索引使用模式和查询频率。 +- `sys.schema_unused_indexes`:列出自数据库上次重启后未被使用的索引。 +- 不可见索引:可在删除前测试移除索引的影响。 + +借助这些可观测性工具,你可以放心清理冗余索引,避免性能下降风险。 + +## 使用 `TIDB_INDEX_USAGE` 追踪索引使用情况 + +自 [TiDB v8.0.0](/releases/release-8.0.0.md) 起,`TIDB_INDEX_USAGE` 系统表可实时洞察索引使用情况,帮助你优化查询性能并移除不必要的索引。 + +具体来说,你可以通过 `TIDB_INDEX_USAGE` 实现: + +- 检测未使用索引:识别未被查询访问的索引,判断是否可安全移除。 +- 分析索引效率:追踪索引使用频率及其对查询执行的贡献。 +- 评估查询模式:了解索引对读操作、数据扫描和 KV 请求的影响。 + +自 [TiDB v8.4.0](/releases/release-8.4.0.md) 起,`TIDB_INDEX_USAGE` 还包含聚簇表的主键,进一步提升索引性能可见性。 + +### `TIDB_INDEX_USAGE` 关键指标 + +如需查看 `TIDB_INDEX_USAGE` 表字段,可执行: + +```sql +USE INFORMATION_SCHEMA; +DESC TIDB_INDEX_USAGE; +``` + +```sql ++--------------------------+-------------+------+------+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++--------------------------+-------------+------+------+---------+-------+ +| TABLE_SCHEMA | varchar(64) | YES | | NULL | | +| TABLE_NAME | varchar(64) | YES | | NULL | | +| INDEX_NAME | varchar(64) | YES | | NULL | | +| QUERY_TOTAL | bigint(21) | YES | | NULL | | +| KV_REQ_TOTAL | bigint(21) | YES | | NULL | | +| ROWS_ACCESS_TOTAL | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_0 | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_0_1 | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_1_10 | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_10_20 | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_20_50 | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_50_100 | bigint(21) | YES | | NULL | | +| PERCENTAGE_ACCESS_100 | bigint(21) | YES | | NULL | | +| LAST_ACCESS_TIME | datetime | YES | | NULL | | ++--------------------------+-------------+------+------+---------+-------+ +共 14 行 +``` + +各字段说明详见 [`TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md)。 + +### 利用 `TIDB_INDEX_USAGE` 识别未使用和低效索引 + +- 未使用索引: + + - `QUERY_TOTAL = 0` 表示该索引未被任何查询使用。 + - `LAST_ACCESS_TIME` 距今较久,说明索引可能已无用。 + +- 低效索引: + + - `PERCENTAGE_ACCESS_100` 数值较大,说明存在全索引扫描,可能为低效索引。 + - 对比 `ROWS_ACCESS_TOTAL` 与 `QUERY_TOTAL`,判断索引每次使用时扫描的行数是否过多。 + +通过 `TIDB_INDEX_USAGE`,你可详细了解索引性能,便于移除冗余索引、优化查询执行。 + +### 高效使用 `TIDB_INDEX_USAGE` 的注意事项 + +#### 数据更新有延迟 + +为降低性能影响,`TIDB_INDEX_USAGE` 数据更新可能延迟最多 5 分钟。分析时请注意该延迟。 + +#### 索引使用数据不持久化 + +`TIDB_INDEX_USAGE` 数据存储于内存,节点重启后数据会丢失。 + +#### 跟踪历史数据 + +可定期导出索引使用快照: + +```sql +SELECT * FROM INFORMATION_SCHEMA.TIDB_INDEX_USAGE INTO OUTFILE '/backup/index_usage_snapshot.csv'; +``` + +通过对比快照,可跟踪索引使用趋势,辅助决策。 + +## 使用 `CLUSTER_TIDB_INDEX_USAGE` 汇总全集群索引数据 + +TiDB 为分布式 SQL 数据库,查询负载分布于多个节点。每个节点独立追踪本地索引使用。若需全局视角,TiDB 提供 [`CLUSTER_TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md#cluster_tidb_index_usage) 系统表,汇总所有节点的索引使用数据,便于优化分布式环境下的索引策略。 + +与单节点的 `TIDB_INDEX_USAGE` 不同,`CLUSTER_TIDB_INDEX_USAGE` 支持: + +- 检测索引使用不一致。例如,某索引在部分节点常用,其他节点未用。 +- 分析分布式查询的全局索引模式,确保索引决策反映实际负载分布。 +- 优化全节点索引策略,提升多节点部署下的查询效率。 + +不同节点负载可能不同。某索引在部分节点未用,但在其他节点关键。可用如下 SQL 按实例分组分析: + +```sql +SELECT INSTANCE, TABLE_NAME, INDEX_NAME, SUM(QUERY_TOTAL) AS total_queries +FROM INFORMATION_SCHEMA.CLUSTER_TIDB_INDEX_USAGE +GROUP BY INSTANCE, TABLE_NAME, INDEX_NAME +ORDER BY total_queries DESC; +``` + +帮助判断索引是否在所有节点都未用,辅助安全移除。 + +### `TIDB_INDEX_USAGE` 与 `CLUSTER_TIDB_INDEX_USAGE` 区别 + +| 功能 | `TIDB_INDEX_USAGE` | `CLUSTER_TIDB_INDEX_USAGE` | +| --------------- | ----------------------------------------- | -------------------------------------------- | +| 作用范围 | 单一数据库实例内索引使用 | 汇总整个 TiDB 集群的索引使用 | +| 索引追踪 | 数据为本地实例级 | 提供集群级统一视图 | +| 主要用途 | 实例级调试索引使用 | 分析全局索引模式及多节点行为 | + +### 高效使用 `CLUSTER_TIDB_INDEX_USAGE` 的注意事项 + +- 数据更新有延迟 + + 同样为降低性能影响,数据更新可能延迟最多 5 分钟。 + +- 内存存储 + + 与 `TIDB_INDEX_USAGE` 一样,节点重启后数据丢失。 + +通过 `CLUSTER_TIDB_INDEX_USAGE`,可获得全局索引行为视角,确保索引策略与分布式负载匹配。 + +## 使用 `schema_unused_indexes` 快速识别未使用索引 + +手动分析索引使用数据较为繁琐。TiDB 提供 [`schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 视图,自动列出自上次数据库重启后未被使用的索引。 + +这样你可以: + +- 快速识别不再使用的索引,降低存储成本。 +- 通过移除无用索引,加速 DML 操作(如 `INSERT`、`UPDATE`、`DELETE`)。 +- 无需手动分析查询模式,简化索引审计。 + +### `schema_unused_indexes` 工作原理 + +该视图基于 `TIDB_INDEX_USAGE`,自动筛选出自上次 TiDB 重启后查询次数为零的索引。 + +查询未使用索引: + +```sql +SELECT * FROM sys.schema_unused_indexes; +``` + +返回类似如下结果: + +``` ++-----------------+---------------+--------------------+ +| object_schema | object_name | index_name | ++---------------- + ------------- + -------------------+ +| bookshop | users | nickname | +| bookshop | ratings | uniq_book_user_idx | ++---------------- + ------------- + -------------------+ +``` + +### 使用 `schema_unused_indexes` 的注意事项 + +#### 仅统计自上次重启以来未用索引 + +- TiDB 节点重启后,使用数据会被重置。 +- 建议系统运行一段时间,确保捕获到有代表性的业务负载后再参考该数据。 + +#### 并非所有未用索引都可立即删除 + +部分索引虽很少用,但对特定查询、批处理或报表任务仍然重要。删除前请确认是否支持: + +- 低频但关键的查询,如月度报表、分析任务 +- 非每日运行的批处理作业 +- 临时排查用的查询 + +如索引仅在重要但不频繁的查询中出现,建议先保留或设为不可见。 + +可使用[不可见索引](#安全测试索引移除:使用不可见索引)先行测试。 + +### 手动创建 `schema_unused_indexes` 视图 + +如从旧版本升级到 TiDB v8.0.0 及以上,需手动创建系统 schema 及相关视图。 + +详见[手动创建 `schema_unused_indexes` 视图](/sys-schema/sys-schema-unused-indexes.md#manually-create-the-schema_unused_indexes-view)。 + +## 安全测试索引移除:使用不可见索引 + +直接删除索引可能带来性能风险,尤其是那些虽不常用但对特定查询仍关键的索引。 + +为降低风险,TiDB 支持不可见索引,可临时禁用索引但不删除。这样你可安全验证移除决策,确保数据库优化过程更可控。 + +### 什么是不可见索引? + +不可见索引仍保留在数据库中,但优化器会忽略它。可通过 [`ALTER TABLE ... INVISIBLE`](/sql-statements/sql-statement-alter-table.md) 将索引设为不可见,测试其是否真的无用。 + +主要优势: + +- **安全测试**:查询不再使用该索引,若需恢复可随时还原。 +- **无存储影响**:索引结构未变,无需重建。 +- **性能监控**:可观察禁用索引后的查询表现,辅助决策。 + +### 设置索引为不可见 + +示例 SQL: + +```sql +ALTER TABLE bookshop.users ALTER INDEX nickname INVISIBLE; +``` + +设置后,观察系统查询性能: + +- 若性能无明显变化,说明索引可安全移除。 +- 若查询延迟上升,说明索引仍有必要。 + +### 高效使用不可见索引 + +- **建议在业务低峰期测试**,便于监控影响。 +- **结合查询监控工具**,对比索引可见与不可见时的执行计划。 +- **覆盖多种业务场景**,确保索引不被特殊报表或定时任务依赖。 + +### 不可见索引建议保留多久? + +- OLTP 业务:建议至少观察一周,覆盖日常波动。 +- 批处理/ETL:建议覆盖完整报表周期,如月度财务报表。 +- 临时分析查询:结合查询日志确认无依赖后再删除。 + +为安全起见,建议至少覆盖一个完整业务周期后再做最终决策。 + +## 索引优化五大最佳实践 + +为保持高性能和资源高效,索引优化应成为数据库维护的常规工作。TiDB 索引管理建议: + +1. **定期监控索引使用** + + - 利用 [`TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) 和 [`CLUSTER_TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md#cluster_tidb_index_usage) 追踪索引活动。 + - 通过 [`schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 识别未用索引,评估是否可移除。 + - 监控查询执行计划,发现可能导致高 I/O 的低效索引。 + +2. **移除索引前务必验证** + + - 使用 [`ALTER TABLE ... INVISIBLE`](/sql-statements/sql-statement-alter-table.md) 将索引设为不可见,观察影响后再决定是否删除。 + - 若查询性能稳定,可考虑移除索引。 + - 观察期应覆盖所有业务场景,确保安全。 + +3. **优化现有索引** + + - 合并冗余索引,减少存储和写入开销。若多个索引服务类似查询,可合并为更高效的复合索引。 + + - 查找前缀重叠的索引,可执行: + + ```sql + SELECT TABLE_SCHEMA, TABLE_NAME, INDEX_NAME, COLUMN_NAME, SEQ_IN_INDEX + FROM INFORMATION_SCHEMA.STATISTICS + WHERE TABLE_NAME = 'your_table' + ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, SEQ_IN_INDEX; + ``` + + - 若两个索引前导列相同,建议合并为复合索引。 + + - 提高选择性。低选择性索引(过滤行数少)可通过: + + - 增加列提升过滤效率。 + - 调整索引结构(如前缀索引、复合索引)。 + + - 利用 `TIDB_INDEX_USAGE` 的 `PERCENTAGE_ACCESS_*` 字段分析索引选择性。 + +4. **关注 DML 性能影响** + + - 避免过度索引。每增加一个索引,`INSERT`、`UPDATE`、`DELETE` 的维护成本都会上升。 + - 仅为查询必要字段建索引,降低写入负担。 + +5. **定期测试与调优** + + - 定期进行索引审计,尤其在业务负载变化后。 + - 利用 TiDB 执行计划分析工具,验证索引是否被高效使用。 + - 新增索引建议先在隔离环境测试,避免性能回退。 + +遵循以上最佳实践,可确保查询高效、存储开销最小、数据库性能最优。 From 93ae383a650f358a5b8d4d349477dc4432335162 Mon Sep 17 00:00:00 2001 From: houfaxin Date: Thu, 11 Sep 2025 14:54:19 +0800 Subject: [PATCH 2/5] Update index-management-best-practices.md --- .../index-management-best-practices.md | 110 ++++++++++-------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/best-practices/index-management-best-practices.md b/best-practices/index-management-best-practices.md index 76de59757a0c..8349ae8b606f 100644 --- a/best-practices/index-management-best-practices.md +++ b/best-practices/index-management-best-practices.md @@ -15,9 +15,9 @@ summary: 了解在 TiDB 中管理和优化索引、识别并移除未使用索 主动识别和优化索引有助于: - 降低存储开销:移除未使用索引可释放磁盘空间,降低长期存储成本。 -- 提升写入性能:写密集型场景(如 `INSERT`、`UPDATE`、`DELETE`)在减少不必要索引维护后性能更佳。 -- 优化查询执行:高效索引减少扫描行数,加快查询速度和响应时间。 -- 简化数据库管理:索引更少且优化后,备份、恢复和结构变更更简单。 +- 提升写入性能:写密集型场景(如 `INSERT`、`UPDATE`、`DELETE`)在减少不必要索引维护后,性能更佳。 +- 优化查询执行:高效索引能够减少扫描行数,加快查询速度和响应时间。 +- 简化数据库管理:减少并优化索引后,可以简化备份、恢复和数据库变更。 由于索引会随业务逻辑变化而演进,定期索引审计是数据库维护的标准流程。TiDB 提供内置可观测性工具,帮助你安全高效地检测、评估和优化索引。 @@ -32,7 +32,7 @@ TiDB v8.0.0 引入了 [`INFORMATION_SCHEMA.TIDB_INDEX_USAGE`](/information-schem - 实时追踪索引使用:识别索引访问频率及其对性能的贡献。 - 检测未使用索引:定位自上次数据库重启后未被使用的索引。 - 评估索引效率:判断索引是否有效过滤数据,或带来过多 I/O 开销。 -- 安全测试索引移除:可先将索引设为不可见,确保无查询依赖后再删除。 +- 安全测试索引移除:可先将索引暂时设为不可见,确保无查询依赖后再删除。 TiDB 通过以下强大工具简化索引优化: @@ -44,19 +44,19 @@ TiDB 通过以下强大工具简化索引优化: ## 使用 `TIDB_INDEX_USAGE` 追踪索引使用情况 -自 [TiDB v8.0.0](/releases/release-8.0.0.md) 起,`TIDB_INDEX_USAGE` 系统表可实时洞察索引使用情况,帮助你优化查询性能并移除不必要的索引。 +从 [TiDB v8.0.0](/releases/release-8.0.0.md) 开始,你可以使用 `TIDB_INDEX_USAGE` 系统表实时观测索引使用情况,帮助你优化查询性能并移除不必要的索引。 -具体来说,你可以通过 `TIDB_INDEX_USAGE` 实现: +具体来说,你可以通过 `TIDB_INDEX_USAGE` 进行以下操作: - 检测未使用索引:识别未被查询访问的索引,判断是否可安全移除。 - 分析索引效率:追踪索引使用频率及其对查询执行的贡献。 - 评估查询模式:了解索引对读操作、数据扫描和 KV 请求的影响。 -自 [TiDB v8.4.0](/releases/release-8.4.0.md) 起,`TIDB_INDEX_USAGE` 还包含聚簇表的主键,进一步提升索引性能可见性。 +从 [TiDB v8.4.0](/releases/release-8.4.0.md) 开始,`TIDB_INDEX_USAGE` 还包含聚簇表的主键,进一步提升索引性能可见性。 ### `TIDB_INDEX_USAGE` 关键指标 -如需查看 `TIDB_INDEX_USAGE` 表字段,可执行: +如需查看 `TIDB_INDEX_USAGE` 表字段,可执行以下 SQL 语句: ```sql USE INFORMATION_SCHEMA; @@ -85,9 +85,11 @@ DESC TIDB_INDEX_USAGE; 共 14 行 ``` -各字段说明详见 [`TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md)。 +各字段说明,请详见 [`TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md)。 -### 利用 `TIDB_INDEX_USAGE` 识别未使用和低效索引 +### 利用 `TIDB_INDEX_USAGE` 识别未使用和低效的索引 + +本节介绍如何利用 `TIDB_INDEX_USAGE` 系统表识别未使用和低效的索引。 - 未使用索引: @@ -101,37 +103,39 @@ DESC TIDB_INDEX_USAGE; 通过 `TIDB_INDEX_USAGE`,你可详细了解索引性能,便于移除冗余索引、优化查询执行。 -### 高效使用 `TIDB_INDEX_USAGE` 的注意事项 +### 高效使用 `TIDB_INDEX_USAGE` + +以下要点可以帮助你高效使用 `TIDB_INDEX_USAGE` 系统表。 #### 数据更新有延迟 -为降低性能影响,`TIDB_INDEX_USAGE` 数据更新可能延迟最多 5 分钟。分析时请注意该延迟。 +为降低性能影响,`TIDB_INDEX_USAGE` 的数据并非实时更新,索引使用指标可能会有最多 5 分钟的延迟。在分析查询时请注意这一时效性。 #### 索引使用数据不持久化 -`TIDB_INDEX_USAGE` 数据存储于内存,节点重启后数据会丢失。 +`TIDB_INDEX_USAGE` 数据存储于内存,不会在节点中永久储存,在节点重启后数据会丢失。 #### 跟踪历史数据 -可定期导出索引使用快照: +你可以定期导出索引使用快照: ```sql SELECT * FROM INFORMATION_SCHEMA.TIDB_INDEX_USAGE INTO OUTFILE '/backup/index_usage_snapshot.csv'; ``` -通过对比快照,可跟踪索引使用趋势,辅助决策。 +通过对比快照,可以跟踪索引使用趋势,辅助决策。 ## 使用 `CLUSTER_TIDB_INDEX_USAGE` 汇总全集群索引数据 TiDB 为分布式 SQL 数据库,查询负载分布于多个节点。每个节点独立追踪本地索引使用。若需全局视角,TiDB 提供 [`CLUSTER_TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md#cluster_tidb_index_usage) 系统表,汇总所有节点的索引使用数据,便于优化分布式环境下的索引策略。 -与单节点的 `TIDB_INDEX_USAGE` 不同,`CLUSTER_TIDB_INDEX_USAGE` 支持: +与在单节点提供洞察的 `TIDB_INDEX_USAGE` 不同,提供集群级视图的 `CLUSTER_TIDB_INDEX_USAGE` 支持下列功能: - 检测索引使用不一致。例如,某索引在部分节点常用,其他节点未用。 - 分析分布式查询的全局索引模式,确保索引决策反映实际负载分布。 - 优化全节点索引策略,提升多节点部署下的查询效率。 -不同节点负载可能不同。某索引在部分节点未用,但在其他节点关键。可用如下 SQL 按实例分组分析: +不同的 TiDB 节点的查询负载可能不同。某索引在部分节点未用,但在其他节点可能至关重要。你可以使用如下 SQL 按实例分组分析: ```sql SELECT INSTANCE, TABLE_NAME, INDEX_NAME, SUM(QUERY_TOTAL) AS total_queries @@ -142,39 +146,45 @@ ORDER BY total_queries DESC; 帮助判断索引是否在所有节点都未用,辅助安全移除。 -### `TIDB_INDEX_USAGE` 与 `CLUSTER_TIDB_INDEX_USAGE` 区别 +### `TIDB_INDEX_USAGE` 与 `CLUSTER_TIDB_INDEX_USAGE` 的区别 + +`TIDB_INDEX_USAGE` 与 `CLUSTER_TIDB_INDEX_USAGE` 的区别如下表所示。 -| 功能 | `TIDB_INDEX_USAGE` | `CLUSTER_TIDB_INDEX_USAGE` | -| --------------- | ----------------------------------------- | -------------------------------------------- | -| 作用范围 | 单一数据库实例内索引使用 | 汇总整个 TiDB 集群的索引使用 | -| 索引追踪 | 数据为本地实例级 | 提供集群级统一视图 | -| 主要用途 | 实例级调试索引使用 | 分析全局索引模式及多节点行为 | +| 功能 | `TIDB_INDEX_USAGE` | `CLUSTER_TIDB_INDEX_USAGE` | +| -------------- | ----------------------------------------- | -------------------------------------------- | +| 作用范围 | 单一数据库实例内索引使用 | 汇总整个 TiDB 集群的索引使用 | +| 索引追踪 | 数据为本地实例级 | 提供集群级统一视图 | +| 主要用途 | 实例级调试索引使用 | 分析全局索引模式及多节点行为 | -### 高效使用 `CLUSTER_TIDB_INDEX_USAGE` 的注意事项 +### 高效使用 `CLUSTER_TIDB_INDEX_USAGE` + +由于 `CLUSTER_TIDB_INDEX_USAGE` 系统表汇总了多个节点的数据,使用时请注意以下事项: - 数据更新有延迟 - 同样为降低性能影响,数据更新可能延迟最多 5 分钟。 + 为将对性能的影响降到最低,`CLUSTER_TIDB_INDEX_USAGE` 不会实时更新。索引使用数据更新可能延迟最多 5 分钟。在分析查询时候请注意该延时。 - 内存存储 - 与 `TIDB_INDEX_USAGE` 一样,节点重启后数据丢失。 + 与 `TIDB_INDEX_USAGE` 一样,在节点重启后,储存在内存中的索引使用数据会丢失。 通过 `CLUSTER_TIDB_INDEX_USAGE`,可获得全局索引行为视角,确保索引策略与分布式负载匹配。 ## 使用 `schema_unused_indexes` 快速识别未使用索引 -手动分析索引使用数据较为繁琐。TiDB 提供 [`schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 视图,自动列出自上次数据库重启后未被使用的索引。 +手动分析索引使用数据较为繁琐。为简化该流程,TiDB 提供了 [`schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 视图,自动列出自上次数据库重启后未被使用的索引。 -这样你可以: +使用该功能,你可以: - 快速识别不再使用的索引,降低存储成本。 - 通过移除无用索引,加速 DML 操作(如 `INSERT`、`UPDATE`、`DELETE`)。 - 无需手动分析查询模式,简化索引审计。 -### `schema_unused_indexes` 工作原理 +通过使用 `schema_unused_indexes`,你可以快速识别不必要的索引,轻松降低数据库开销。 + +### `schema_unused_indexes` 的工作原理 -该视图基于 `TIDB_INDEX_USAGE`,自动筛选出自上次 TiDB 重启后查询次数为零的索引。 +`schema_unused_indexes` 视图基于 `TIDB_INDEX_USAGE`,可以自动筛选出自上次 TiDB 重启后查询次数为零的索引。 查询未使用索引: @@ -195,6 +205,8 @@ SELECT * FROM sys.schema_unused_indexes; ### 使用 `schema_unused_indexes` 的注意事项 +使用 `schema_unused_indexes` 时,注意以下事项。 + #### 仅统计自上次重启以来未用索引 - TiDB 节点重启后,使用数据会被重置。 @@ -202,7 +214,7 @@ SELECT * FROM sys.schema_unused_indexes; #### 并非所有未用索引都可立即删除 -部分索引虽很少用,但对特定查询、批处理或报表任务仍然重要。删除前请确认是否支持: +部分索引虽很少用,但对特定查询、批处理或报表任务仍然重要。删除索引前,请确认该索引是否支持以下功能: - 低频但关键的查询,如月度报表、分析任务 - 非每日运行的批处理作业 @@ -210,7 +222,7 @@ SELECT * FROM sys.schema_unused_indexes; 如索引仅在重要但不频繁的查询中出现,建议先保留或设为不可见。 -可使用[不可见索引](#安全测试索引移除:使用不可见索引)先行测试。 +你可以使用[不可见索引](#使用不可见索引安全移除测试索引)先进行测试。 ### 手动创建 `schema_unused_indexes` 视图 @@ -218,20 +230,20 @@ SELECT * FROM sys.schema_unused_indexes; 详见[手动创建 `schema_unused_indexes` 视图](/sys-schema/sys-schema-unused-indexes.md#manually-create-the-schema_unused_indexes-view)。 -## 安全测试索引移除:使用不可见索引 +## 使用不可见索引安全移除测试索引 直接删除索引可能带来性能风险,尤其是那些虽不常用但对特定查询仍关键的索引。 -为降低风险,TiDB 支持不可见索引,可临时禁用索引但不删除。这样你可安全验证移除决策,确保数据库优化过程更可控。 +为降低风险,TiDB 支持不可见索引,可以临时禁用索引但不删除。这样你可安全验证移除决策,确保数据库优化过程更可控。 ### 什么是不可见索引? -不可见索引仍保留在数据库中,但优化器会忽略它。可通过 [`ALTER TABLE ... INVISIBLE`](/sql-statements/sql-statement-alter-table.md) 将索引设为不可见,测试其是否真的无用。 +不可见索引仍保留在数据库中,但优化器会忽略它。你可以使用 [`ALTER TABLE ... INVISIBLE`](/sql-statements/sql-statement-alter-table.md) 将索引设为不可见,测试其是否真的无用。 -主要优势: +不可见索引有如下优势: -- **安全测试**:查询不再使用该索引,若需恢复可随时还原。 -- **无存储影响**:索引结构未变,无需重建。 +- **安全测试**:查询不再使用该索引,若需恢复可随时快速还原。 +- **对索引存储无影响**:索引结构未变,无需重建。 - **性能监控**:可观察禁用索引后的查询表现,辅助决策。 ### 设置索引为不可见 @@ -244,26 +256,26 @@ ALTER TABLE bookshop.users ALTER INDEX nickname INVISIBLE; 设置后,观察系统查询性能: -- 若性能无明显变化,说明索引可安全移除。 -- 若查询延迟上升,说明索引仍有必要。 +- 若性能无明显变化,说明你可以安全移除该索引。 +- 若查询延迟上升,说明该索引仍有必要保留。 ### 高效使用不可见索引 -- **建议在业务低峰期测试**,便于监控影响。 -- **结合查询监控工具**,对比索引可见与不可见时的执行计划。 -- **覆盖多种业务场景**,确保索引不被特殊报表或定时任务依赖。 +- **建议在业务低峰期测试**:便于在可控环境中监控对性能的影响。 +- **结合查询监控工具**:对比索引可见与不可见时的执行计划。 +- **覆盖多种业务场景**:确保索引不被特殊报表或定时任务依赖。 ### 不可见索引建议保留多久? -- OLTP 业务:建议至少观察一周,覆盖日常波动。 -- 批处理/ETL:建议覆盖完整报表周期,如月度财务报表。 +- OLTP 负载:建议至少观察一周,覆盖日常波动。 +- 批处理或 ETL 负载:建议覆盖完整报表周期,如月度财务报表。 - 临时分析查询:结合查询日志确认无依赖后再删除。 为安全起见,建议至少覆盖一个完整业务周期后再做最终决策。 ## 索引优化五大最佳实践 -为保持高性能和资源高效,索引优化应成为数据库维护的常规工作。TiDB 索引管理建议: +为保持高性能和资源高效,索引优化应成为数据库维护的常规工作。TiDB 索引管理建议如下: 1. **定期监控索引使用** @@ -273,7 +285,7 @@ ALTER TABLE bookshop.users ALTER INDEX nickname INVISIBLE; 2. **移除索引前务必验证** - - 使用 [`ALTER TABLE ... INVISIBLE`](/sql-statements/sql-statement-alter-table.md) 将索引设为不可见,观察影响后再决定是否删除。 + - 使用 [`ALTER TABLE ... INVISIBLE`](/sql-statements/sql-statement-alter-table.md) 将索引设为暂时不可见,观察影响后再决定是否永久删除。 - 若查询性能稳定,可考虑移除索引。 - 观察期应覆盖所有业务场景,确保安全。 @@ -292,9 +304,9 @@ ALTER TABLE bookshop.users ALTER INDEX nickname INVISIBLE; - 若两个索引前导列相同,建议合并为复合索引。 - - 提高选择性。低选择性索引(过滤行数少)可通过: + - 提高选择性。可以通过以下方式优化低选择性索引(即那些过滤行数过多的索引): - - 增加列提升过滤效率。 + - 增加额外的列,以提升过滤效率。 - 调整索引结构(如前缀索引、复合索引)。 - 利用 `TIDB_INDEX_USAGE` 的 `PERCENTAGE_ACCESS_*` 字段分析索引选择性。 From 1e1f41749ff21a785817be6f0ef8e6d3e0e206d3 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Thu, 11 Sep 2025 15:19:19 +0800 Subject: [PATCH 3/5] Update TOC.md --- TOC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TOC.md b/TOC.md index 73ed10bf9ce7..d7bf92f5860c 100644 --- a/TOC.md +++ b/TOC.md @@ -428,7 +428,7 @@ - [TiDB 最佳实践](/best-practices/tidb-best-practices.md) - [DDL 最佳实践](/ddl-introduction.md) - [多列索引优化最佳实践](/best-practices/multi-column-index-best-practices.md) - - [理索引和识别未使用索引的最佳实践](/best-practices/index-management-best-practices.md) + - [管理索引和识别未使用索引的最佳实践](/best-practices/index-management-best-practices.md) - [SaaS 多租户场景下处理百万张表](/best-practices/saas-best-practices.md) - [将 UUID 用作主键的最佳实践](/best-practices/uuid.md) - [Java 应用开发最佳实践](/best-practices/java-app-best-practices.md) From 6a7bee08438caa2650a0d51cdcb91ef1ef859d66 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Thu, 18 Sep 2025 17:02:14 +0800 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Roger Song --- .../index-management-best-practices.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/best-practices/index-management-best-practices.md b/best-practices/index-management-best-practices.md index 8349ae8b606f..ea7726da2a74 100644 --- a/best-practices/index-management-best-practices.md +++ b/best-practices/index-management-best-practices.md @@ -5,7 +5,7 @@ summary: 了解在 TiDB 中管理和优化索引、识别并移除未使用索 # 理索引和识别未使用索引的最佳实践 -索引对于优化数据库查询性能至关重要,可以减少全表扫描的数据量。然而,随着应用演进、业务逻辑变化和数据量增长,索引也会出现效率问题,包括: +索引对于优化数据库查询性能至关重要,可以减少全表扫描的数据量。然而,随着应用演进、业务逻辑变化和数据量增长,原有的索引设计也会遇到问题,包括: - 未使用索引:这些索引曾经有用,但现在查询优化器已不再选择它们,导致占用存储空间并增加写入操作的额外开销。 - 低效索引:某些索引虽然被优化器使用,但扫描的数据量远超预期,增加磁盘 I/O 并拖慢查询速度。 @@ -19,22 +19,22 @@ summary: 了解在 TiDB 中管理和优化索引、识别并移除未使用索 - 优化查询执行:高效索引能够减少扫描行数,加快查询速度和响应时间。 - 简化数据库管理:减少并优化索引后,可以简化备份、恢复和数据库变更。 -由于索引会随业务逻辑变化而演进,定期索引审计是数据库维护的标准流程。TiDB 提供内置可观测性工具,帮助你安全高效地检测、评估和优化索引。 +由于索引会随业务逻辑变化而演进,定期索引审计是数据库维护的标准流程。TiDB 提供内置可观测性手段,帮助你安全高效地观测、评估和优化索引。 -TiDB v8.0.0 引入了 [`INFORMATION_SCHEMA.TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) 表和 [`sys.schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 视图,帮助你追踪索引使用模式,做出数据驱动的决策。 +TiDB v8.0.0 引入了 [`INFORMATION_SCHEMA.TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md) 表和 [`sys.schema_unused_indexes`](/sys-schema/sys-schema-unused-indexes.md) 视图,帮助你追踪索引使用情况,根据运行数据做出正确判断。 本文介绍如何利用这些工具检测并移除未使用或低效索引,从而提升 TiDB 性能与稳定性。 ## TiDB 索引优化:数据驱动的方法 -索引对查询性能至关重要,但如果没有充分分析就移除,可能导致性能回退甚至系统不稳定。为确保索引管理的安全与有效,TiDB 提供内置可观测性工具,支持以下操作: +索引对查询性能至关重要,但如果没有充分分析就移除,可能导致性能回退甚至系统不稳定。为确保索引管理的安全与有效,TiDB 提供内置可观测性手段,支持以下操作: - 实时追踪索引使用:识别索引访问频率及其对性能的贡献。 - 检测未使用索引:定位自上次数据库重启后未被使用的索引。 - 评估索引效率:判断索引是否有效过滤数据,或带来过多 I/O 开销。 - 安全测试索引移除:可先将索引暂时设为不可见,确保无查询依赖后再删除。 -TiDB 通过以下强大工具简化索引优化: +TiDB 通过以下手段简化索引优化: - `INFORMATION_SCHEMA.TIDB_INDEX_USAGE`:监控索引使用模式和查询频率。 - `sys.schema_unused_indexes`:列出自数据库上次重启后未被使用的索引。 @@ -105,7 +105,7 @@ DESC TIDB_INDEX_USAGE; ### 高效使用 `TIDB_INDEX_USAGE` -以下要点可以帮助你高效使用 `TIDB_INDEX_USAGE` 系统表。 +以下要点可以帮助你正确理解并使用 `TIDB_INDEX_USAGE` 系统表。 #### 数据更新有延迟 @@ -113,7 +113,7 @@ DESC TIDB_INDEX_USAGE; #### 索引使用数据不持久化 -`TIDB_INDEX_USAGE` 数据存储于内存,不会在节点中永久储存,在节点重启后数据会丢失。 +`TIDB_INDEX_USAGE` 数据存储于每个 TiDB 实例的内存中,不会持久化,在节点重启后数据会丢失。 #### 跟踪历史数据 @@ -242,7 +242,7 @@ SELECT * FROM sys.schema_unused_indexes; 不可见索引有如下优势: -- **安全测试**:查询不再使用该索引,若需恢复可随时快速还原。 +- **安全测试**:查询不再使用该索引,相关优化器统计信息仍旧会被维护,若需恢复可随时快速还原。 - **对索引存储无影响**:索引结构未变,无需重建。 - **性能监控**:可观察禁用索引后的查询表现,辅助决策。 From 3d48ebd46ce5cf771d9c3e8399d5d981b5b094d3 Mon Sep 17 00:00:00 2001 From: xixirangrang Date: Thu, 18 Sep 2025 17:11:01 +0800 Subject: [PATCH 5/5] Update best-practices/index-management-best-practices.md --- best-practices/index-management-best-practices.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/best-practices/index-management-best-practices.md b/best-practices/index-management-best-practices.md index ea7726da2a74..87558cc0fc58 100644 --- a/best-practices/index-management-best-practices.md +++ b/best-practices/index-management-best-practices.md @@ -129,12 +129,6 @@ SELECT * FROM INFORMATION_SCHEMA.TIDB_INDEX_USAGE INTO OUTFILE '/backup/index_us TiDB 为分布式 SQL 数据库,查询负载分布于多个节点。每个节点独立追踪本地索引使用。若需全局视角,TiDB 提供 [`CLUSTER_TIDB_INDEX_USAGE`](/information-schema/information-schema-tidb-index-usage.md#cluster_tidb_index_usage) 系统表,汇总所有节点的索引使用数据,便于优化分布式环境下的索引策略。 -与在单节点提供洞察的 `TIDB_INDEX_USAGE` 不同,提供集群级视图的 `CLUSTER_TIDB_INDEX_USAGE` 支持下列功能: - -- 检测索引使用不一致。例如,某索引在部分节点常用,其他节点未用。 -- 分析分布式查询的全局索引模式,确保索引决策反映实际负载分布。 -- 优化全节点索引策略,提升多节点部署下的查询效率。 - 不同的 TiDB 节点的查询负载可能不同。某索引在部分节点未用,但在其他节点可能至关重要。你可以使用如下 SQL 按实例分组分析: ```sql