---
title: 'TiDB 社区智慧合集丨解码 TiDB 性能谜题：让你的数据库发挥最强动力！'
date: '2024-03-07T20:23:00+08:00'
status: publish
permalink: /blog/decode-tidb-performance-puzzles
author: '周, 盛虎'
excerpt: '这篇帖子收集整理了大家推荐的各个方面的 TiDB 数据库性能优化方法，欢迎各位 TiDBer 持续补充更新。'
type: post
id: 6356
category:
    - 案例实践
tag:
    - 'TiDB 性能调优'
post_format: []
profile:
    - PingCAP
---
来自社区，回归社区。非常感谢各位 TiDBer 在之前 【TiDBer 唠嗑茶话会丨征集 TiDB 数据库性能优化大师，你是如何优化 TiDB 数据库性能的呐？】( <https://asktug.com/t/topic/1005563> )里提供的各种性能优化方法。这篇帖子收集整理了大家推荐的各个方面的 [TiDB 数据库性能优化](https://cn.pingcap.com/blog/tag/tidb-performance-tuning/ "TiDB 数据库性能优化")方法，欢迎各位 TiDBer 持续补充更新～

硬件和网络优化
-------

**方法 1**

贡献者：@kongdom

开启 Raid 卡缓存，使机械硬盘的 I/O 性能直线提升。

```
MegaCli64 -LDInfo -Lall -aALL #查看
MegaCli64 -LDSetProp -WB -Lall -aAll #有电池启用缓存
MegaCli64 -LDSetProp CachedBadBBU -Lall -aALL #没有电池启用缓存
MegaCli64 -LDSetProp NOCachedBadBBU -Lall -aALL #没有电池关闭缓存
```

注意：必须保证 Raid 卡的电池正常，否则意外断电会导致数据丢失

**方法 2**

贡献者：@tomxu

1. 优化磁盘性能：使用高性能 SSD 硬盘以减少磁盘 I/O 延迟。
2. 优化网络性能：使用高速网络设备和优化网络拓扑结构以降低网络延迟。
3. 优化 CPU 和内存：确保 TiDB 集群有足够的 CPU 和内存资源，以便在高负载下保持良好的性能。

**方法 3**

贡献者：@ShawnYan

dstat 查看当前硬件资源状态

**方法 4**

贡献者：@TiDBer\_ 小小

硬件优化：对硬件进行优化，升级硬件、调整硬件参数、调整系统参数、优化系统配置。

SQL 方面优化
--------

**方法 1**

贡献者：@tidb 菜鸟一只

一、

1. 先看执行计划，最简单的，看看是不是缺索引，是的话，直接加索引；
2. 如果因为统计信息太旧导致执行计划异常，直接重新收集统计信息；
3. 统计信息很新但是执行计划仍然不对，指定 hint；
4. SQL 执行计划都对，但是速度还是不理想，如果是 OLTP 请求，改写 SQL 或者联系开发修改应用逻辑；
5. SQL 执行计划对，但是速度不理想，如果是 OLAP 请求，直接上 TiFlash

二、  
如果以上都做了，性能还达不到要求，那么【参数层面优化】

1. 看看是不是某些参数设置有问题，能在线修改参数的直接在线修改；
2. 不能在线修改的，修改配置文件参数后 reload 集群

三、  
再看主机资源

1. 是不是有主机其他进程挤占主机资源；
2. 看看主机的参数是否可以优化

四、  
以上方法都用过了，发现性能还是达不到：  
评估当前集群的资源利用率，不足直接向老板申请扩容

**方法 2**

贡献者：@裤衩儿飞上天

1. 规范开发
2. 把慢 SQL 优化掉，基本能解决 80%的数据库问题
3. 升级硬件

查询优化
----

**方法 1**

贡献者：@coderv

可以通过分片、路由等技术来避免大量的热点数据，从而提高系统的可扩展性和可用性。在编写 SQL 语句时，应该尽量减少全表扫描，使用合适的索引来提高查询性能。比如可以使用覆盖索引、前缀索引、联合索引等技术来减少索引占用空间、提高查询效率。

**方法 2**

贡献者：@tomxu

1. 使用索引 ：为经常用于查询条件和排序的列创建索引。这将有助于提高查询效率。
2. 避免全表扫描 ：通过使用索引避免全表扫描。
3. 优化复杂查询 ：将复杂查询分解为多个简单查询，以提高查询效率。
4. 使用 EXPLAIN 分析查询计划 ：通过 EXPLAIN 命令分析查询计划，找出慢查询的原因并进行优化
5. 避免使用子查询 ：尽量将子查询转换为 JOIN 查询，以提高查询效率。

**方法 3**

贡献者：@凌云 Cloud

1. 使用合适的索引：根据查询语句的特点和数据分布情况，选择合适的单列或多列索引。对于复杂的查询，可以考虑使用覆盖索引或索引合并等技术来提高性能。
2. 避免全表扫描：尽可能地使用索引来避免全表扫描。如果无法使用索引，可以考虑将数据划分为更小的分区或者分页查询。
3. 使用连接查询时，避免过度连接：连接查询会增加查询的复杂度和执行时间。可以考虑使用子查询、关联子查询、EXISTS 或者 NOT EXISTS 等方式来代替连接查询。

**方法 4**

贡献者：@TiDBer\_ 小小

对数据库查询语句进行优化，包括选择合适的索引、使用合适的查询语句、调整查询参数。

**方法 5**

贡献者：@Soysauce520

1. 根据 cluster\_slow\_query 找到开销较大的 SQL 分析优化可能性。
2. 没有优化空间，就需要扩容。

**方法 6**

贡献者：@SoloX

通过分析业务需求和 SQL 执行计划，使用合适的索引、避免全表扫描、调整 SQL 语句等方式来提高查询性能。

统计信息优化
------

**方法 1**

贡献者：@tomxu

1. 更新统计信息：定期更新统计信息以帮助优化器生成更好的查询计划。
2. 调整统计信息收集参数：根据实际情况调整统计信息收集参数以提高优化器的准确性。

**方法 2**

贡献者：@SoloX

定期收集统计信息并更新，使用多列统计信息以优化复杂查询的执行计划。

数据库应用优化
-------

**方法 1**

贡献者：@Jellybean

如何通过应用程序的调整和优化来提高数据库性能？包括缓存、分表、批量操作等优化方法

1. 程序里面 select 语句必须指定要选择的列，不允许 select \* 用法，做好上线和测试工作
2. 对于批量 insert 场景，必须开启批量提交，客户端和服务端参数都好调整
3. 对于批量 update 和 delete 场景，提前和业务沟通，尽量减少此类批量操作，转而通过 replace 扥方式或业务优化调整
4. 对于有大量数据存储和有时限的表，我们也不建议分表，而且使用分区表，对过期的数据直接通过高效的删分区方式完成，而不是低效的批量 delete 方式
5. 对于高频访问的只有几千行的小型表，设置为缓存表，可以将每秒过万的 select 延迟从 5ms 下降到 1ms 左右
6. 对于有大量中间计算结果需要复用的应用，我们使用内存临时表实现

**方法 2**

贡献者：@tomxu

1. 分页查询优化：使用 LIMIT 和 OFFSET 进行分页查询时，尽量避免使用较大的 OFFSET，以降低查询延迟。
2. 合理使用事务：减少长事务，避免大量行锁争用。
3. 减少连接数：通过连接池复用数据库连接，避免过多的数据库连接导致资源竞争。
4. 批量操作：针对大量的 INSERT、UPDATE、DELETE 操作，可以使用批量操作来提高性能。

**方法 3**

贡献者：@SoloX

利用缓存技术减少对数据库的访问，采用分表策略解决单表过大的问题，使用批量操作减少数据库交互次数。

TiDB 集群优化
---------

贡献者：@tomxu

1. 扩展集群：按需添加更多的 TiDB、TiKV 和 PD 节点，实现集群的水平扩展。
2. 调整 TiKV 参数：根据实际负载情况调整 TiKV 的参数，如 raftstore.store-pool-size 、 rocksdb.max-background-jobs 等。
3. 调整 PD 参数：根据实际负载情况调整 PD 的参数，如 scheduler.limit 等。

更多优化方法
------

**方法 1**

贡献者：@TiCQ

【硬优化】硬件优化一般不可主导，每个业务都尽最大建议给“能力之内”的配置！

【软优化】读写优化 90%在 SQL 层面，使用常规 SQL 优化方法进行相关优化处理；再配合数据库系统优化参数进行设置调优。

**方法 2**

贡献者：@老田牛

关键在于确定性能问题的具体位置。例如，对于慢 SQL 的问题，需要确定是单次执行慢还是大量类似的语句导致整体操作系统变慢。如果确定是单个 SQL 慢，就需要检查执行计划是否合理，是 I/O 还是 CPU 造成的慢，是缺少索引还是统计信息的问题。对于 I/O 问题，需要了解如何收集系统的 I/O 数据，确定是单个磁盘 I/O 慢还是整个系统 I/O 慢，是否有硬件报警。

**方法 3**

贡献者：@张雨齐 0720

不同问题有不同的优化手段。比如，慢 SQL 那就优化 SQL，系统参数设置不当就调整参数，其实应该要具体问题具体分析。不过大部分第一件时间是捞资源使用情况和慢 SQL。

**方法 4**

贡献者：@db\_user

初始配置先从 analyze 收集的时间段、慢 SQL、不合适的表结构方面优化，如果在这些方面都已经做到最佳状态，但性能仍然不理想，那么就需要考虑硬件瓶颈的可能性。

**方法 5**

贡献者：@xfworld

把 TiDB 提供的 Dashboard 用好，就能解决很多 Top 级别的问题；

然后在通过 Ggrafana 检测和排查一些重要的指标，可以从更深度的计算、网络、资源调度方面做优化。

**方法 6**

贡献者：@半瓶醋仙

1. 评估业务性质，查询优化：添加索引，数据分片降低查询复杂度，统计信息优化：配置实时更新。
2. 硬件和网络优化：在线运维 Dashboard 和 Grafana 打开看磁盘 I/O，CPU，内存网络流量。TiDB 集群优化：刷参数配置脚本。
3. 数据库应用优化：每日 DBA 巡检日志对比，加载 API 插件。

**方法 7**

贡献者：@bert

原则上， 性能优化也是按需按目标执行，执行 pdca 的过程。分为硬件和软件优化，有如下建议：

1. 评估当前系统性能。TiUP 已经集成了 ch(CH-benCHmark)/TPCC(TPC-C)/TPCH(TPC-H)/YCSB(Yahoo! Cloud Serving Benchmark) 四种测试工具集，使用其进行测试得到系统的基础数据。
2. 选择适合的 TiDB 架构，考虑 TiDB 和 TiFlash 的组合，节点数的配置。硬件的选择等。
3. 优化应用的数据类型和索引。
4. 能批量的操作尽量批量操作，能压缩的压缩，能分区的分区存储。
5. 管理库的统计信息，合理安排统计信息收集时间，调成平行数量。
6. 监控日常的软硬件性能，如 CPU、内存、磁盘 I/O、网络等。根据监控结果调整数据库参数、优化数据类型和索引等，以提高性能。
7. 定期检查和升级 TiDB 数据库软件和硬件，确保其处于最新状态，可以提高性能和稳定性。

**方法 8**

贡献者：@清风明月

1. 版本信息 select tidb\_version();
2. 查看数据库 show databases;
3. 创建数据库 create database tidb;
4. 进入数据库 user tidb;
5. 查看表 show tables;
6. 链接查询 show processlist;
7. 开启角色 set role all;
8. 查看角色 select current\_role();
9. 查看授权 show grants

✨感谢大家贡献的数据库性能优化小技巧~

记得点赞收藏，可以随时在你的个人收藏夹里查看到~

未来我们将继续发布更多来自社区的精品内容，希望能为大家提供更多有价值的信息和经验。

<div class="button-group item-start"> [下载 TiDB 社区版](/product-community/) [咨询 TiDB 企业版](/contact#submit-form)<div>[免费试用 TiDB Cloud](https://tidbcloud.com/free-trial?utm_source=website_cn&utm_medium=direct&utm_campaign=blog)<div class="text-center text-small mt-sm">适用于中国出海企业和开发者</div> </div> </div>