数据库性能取决于数据库层面的多个因素,例如表、查询和配置设置。这些软件构造会在硬件层面产生 CPU 和 I/O 操作,你必须尽量减少这些操作并使其尽可能高效。在进行数据库性能优化时,你首先需要学习软件层面的高级规则和指南,并使用实时时钟时间来衡量性能。随着你成为专家,你会更多地了解内部发生的情况,并开始测量诸如 CPU 周期和 I/O 操作等指标。Database performance depends on several factors at the database level, such as tables, queries, and configuration settings. These software constructs result in CPU and I/O operations at the hardware level, which you must minimize and make as efficient as possible. As you work on database performance, you start by learning the high-level rules and guidelines for the software side, and measuring performance using wall-clock time. As you become an expert, you learn more about what happens internally, and start measuring things such as CPU cycles and I/O operations.
典型用户的目标是从现有的软件和硬件配置中获得最佳的数据库性能。高级用户则会寻找机会来改进 MySQL 软件本身,或者开发自己的存储引擎和硬件设备,以扩展 MySQL 生态系统。Typical users aim to get the best database performance out of their existing software and hardware configurations. Advanced users look for opportunities to improve the MySQL software itself, or develop their own storage engines and hardware appliances to expand the MySQL ecosystem.
使数据库应用程序运行快速的最重要因素是其基本设计:The most important factor in making a database application fast is its basic design:
表是否结构合理?特别是,列是否具有正确的数据类型,每个表是否具有适合工作类型的适当列?例如,执行频繁更新的应用程序通常具有许多列较少的表,而分析大量数据的应用程序通常具有少量列较多的表。Are the tables structured properly? In particular, do the columns have the right data types, and does each table have the appropriate columns for the type of work? For example, applications that perform frequent updates often have many tables with few columns, while applications that analyze large amounts of data often have few tables with many columns.
是否有合适的索引来提高查询效率?Are the right indexes in place to make queries efficient?
您是否为每个表使用了适当的存储引擎,并充分利用所使用的每种存储引擎的优势和功能?特别是,选择一个事务性存储引擎,比如
InnoDB,或者一个非事务性存储引擎,比如MyISAM,对于性能和可扩展性可能非常重要。Are you using the appropriate storage engine for each table, and taking advantage of the strengths and features of each storage engine you use? In particular, the choice of a transactional storage engine such asInnoDBor a nontransactional one such asMyISAMcan be very important for performance and scalability.NoteInnoDB是新表的默认存储引擎。实际上,先进的InnoDB性能特性意味着InnoDB表通常比更简单的MyISAM表表现更好,尤其是在繁忙的数据库中。InnoDBis the default storage engine for new tables. In practice, the advancedInnoDBperformance features mean thatInnoDBtables often outperform the simplerMyISAMtables, especially for a busy database.每个表是否使用了适当的行格式?这个选择也取决于表使用的存储引擎。特别是,压缩表占用更少的磁盘空间,因此读写数据所需的磁盘 I/O 较少。压缩功能适用于各类
InnoDB表的工作负载,以及只读的MyISAM表。Does each table use an appropriate row format? This choice also depends on the storage engine used for the table. In particular, compressed tables use less disk space and so require less disk I/O to read and write the data. Compression is available for all kinds of workloads withInnoDBtables, and for read-onlyMyISAMtables.该应用程序是否使用了适当的锁策略?例如,在可能的情况下允许共享访问,以便数据库操作可以并发运行,以及在适当的时候请求独占访问,以便关键操作获得最高优先级。同样,存储引擎的选择也是很重要的。
InnoDB存储引擎可以处理大多数锁问题,无需您的干预,从而提高数据库的并发性,并减少对代码进行实验和调优的需求。Does the application use an appropriate locking strategy? For example, by allowing shared access when possible so that database operations can run concurrently, and requesting exclusive access when appropriate so that critical operations get top priority. Again, the choice of storage engine is significant. TheInnoDBstorage engine handles most locking issues without involvement from you, allowing for better concurrency in the database and reducing the amount of experimentation and tuning for your code.所有用于缓存的内存区域的大小都设置正确吗?也就是说,它们是否足够大以容纳经常访问的数据,但又不会大到导致物理内存过载和分页。需要配置的主要内存区域是
InnoDB缓冲池和MyISAM键缓存。Are all memory areas used for caching sized correctly? That is, large enough to hold frequently accessed data, but not so large that they overload physical memory and cause paging. The main memory areas to configure are theInnoDBbuffer pool and theMyISAMkey cache.
随着数据库越来越繁忙,任何数据库应用最终都会遇到硬件限制。DBA 必须评估是否可以调优应用或重新配置服务器以避免这些瓶颈,或者是否需要更多的硬件资源。系统瓶颈通常来自以下来源:Any database application eventually hits hardware limits as the database becomes more and more busy. A DBA must evaluate whether it is possible to tune the application or reconfigure the server to avoid these bottlenecks, or whether more hardware resources are required. System bottlenecks typically arise from these sources:
磁盘寻道。磁盘找到一条数据需要时间。对于现代磁盘,这个平均时间通常低于 10 毫秒,因此理论上我们每秒可以进行大约 100 次寻道。随着新磁盘的出现,这个时间慢慢改善,并且很难针对单个表进行优化。优化寻道时间的方法是将数据分布到多个磁盘上。Disk seeks. It takes time for the disk to find a piece of data. With modern disks, the mean time for this is usually lower than 10ms, so we can in theory do about 100 seeks a second. This time improves slowly with new disks and is very hard to optimize for a single table. The way to optimize seek time is to distribute the data onto more than one disk.
磁盘读写。当磁盘到达正确位置时,我们需要读取或写入数据。对于现代磁盘,一块磁盘的吞吐量至少为 10–20MB/s。这比寻道更容易优化,因为你可以从多个磁盘并行读取。Disk reading and writing. When the disk is at the correct position, we need to read or write the data. With modern disks, one disk delivers at least 10–20MB/s throughput. This is easier to optimize than seeks because you can read in parallel from multiple disks.
CPU 周期。当数据在主内存中时,我们必须处理它以得到结果。相对于内存容量而言,大表是最常见的限制因素。但对于小表,速度通常不是问题。CPU cycles. When the data is in main memory, we must process it to get our result. Having large tables compared to the amount of memory is the most common limiting factor. But with small tables, speed is usually not the problem.
内存带宽。当 CPU 需要的数据超过 CPU 缓存能容纳的容量时,主内存带宽就会成为瓶颈。对于大多数系统来说,这是一个不常见的瓶颈,但需要注意。Memory bandwidth. When the CPU needs more data than can fit in the CPU cache, main memory bandwidth becomes a bottleneck. This is an uncommon bottleneck for most systems, but one to be aware of.
要在可移植的 MySQL 程序中使用面向性能的 SQL 扩展,可以在语句中将 MySQL 特定关键字用 /*! */ 注释定界符包裹起来。其他 SQL 服务器会忽略这些被注释的关键字。有关编写注释的信息,请参阅 第 11.7 节,“注释”。To use performance-oriented SQL extensions in a portable MySQL
program, you can wrap MySQL-specific keywords in a statement
within /*! */ comment delimiters. Other SQL
servers ignore the commented keywords. For information about
writing comments, see Section 11.7, “Comments”.