Documentation Home
MySQL 8.0 参考手册  / 第8章优化  / 8.4 优化数据库结构  / 8.4.3 优化多表  /  8.4.3.1 MySQL如何打开和关闭表

8.4.3.1 MySQL如何打开和关闭表

当您执行mysqladmin status 命令时,您应该看到如下内容:

Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12

Open tables如果您的表少于 12 个,那么 12 的值可能有点令人费解。

MySQL 是多线程的,因此可能有许多客户端同时对给定表发出查询。为了尽量减少多个客户端会话在同一个表上具有不同状态的问题,表由每个并发会话独立打开。这会使用额外的内存,但通常会提高性能。对于MyISAM表,每个打开表的客户端的数据文件都需要一个额外的文件描述符。(相比之下,索引文件描述符在所有会话之间共享。)

table_open_cache和 系统变量影响服务器保持打开 的max_connections最大文件数。如果增加其中一个或两个值,您可能会遇到操作系统对每个进程打开的文件描述符数量施加的限制。许多操作系统允许您增加打开文件的限制,尽管该方法因系统而异。请查阅您的操作系统文档以确定是否可以增加限制以及如何增加限制。

table_open_cache是相关的max_connections。例如,对于 200 个并发运行连接,指定表缓存大小至少为,其中 是您执行的任何查询中每个连接的最大表数。您还必须为临时表和文件保留一些额外的文件描述符。 200 * NN

确保您的操作系统可以处理设置所暗示的打开文件描述符的数量 table_open_cache。如果 table_open_cache设置得太高,MySQL 可能会用完文件描述符并出现拒绝连接或无法执行查询等症状。

还要考虑到MyISAM 存储引擎需要为每个唯一的打开表提供两个文件描述符。要增加 MySQL 可用的文件描述符的数量,请设置 open_files_limit系统变量。请参阅第 B.3.2.16 节,“未找到文件和类似错误”

打开表的缓存保持在 table_open_cache条目级别。服务器在启动时自动调整缓存大小。要明确设置大小,请 table_open_cache在启动时设置系统变量。MySQL 可能会暂时打开比这更多的表来执行查询,如本节后面所述。

在以下情况下,MySQL 会关闭未使用的表并将其从表缓存中移除:

当表缓存填满时,服务器使用以下过程来定位要使用的缓存条目:

  • 当前未使用的表被释放,从最近最少使用的表开始。

  • 如果必须开新表,但缓存已满,无法释放表,则根据需要临时扩展缓存。当缓存处于临时扩展状态并且表从已使用状态变为未使用状态时,该表将关闭并从缓存中释放。

MyISAM为每个并发访问打开 一个表。这意味着如果两个线程访问同一个表或者如果一个线程在同一个查询中访问表两次(例如,通过将表连接到自身),则需要打开该表两次。每个并发打开都需要表缓存中的一个条目。任何表的第一次打开都 MyISAM需要两个文件描述符:一个用于数据文件,一个用于索引文件。表的每次额外使用只需要一个数据文件的文件描述符。索引文件描述符在所有线程之间共享。

如果您正在使用该语句打开一个表,则会为该线程分配一个专用表对象。此表对象不被其他线程共享,并且在线程调用或线程终止之前不会关闭。发生这种情况时,表将放回表缓存中(如果缓存未满)。请参阅 第 13.2.4 节,“HANDLER 语句”HANDLER tbl_name OPENHANDLER tbl_name CLOSE

要确定您的表缓存是否太小,请检查 Opened_tables状态变量,该变量指示自服务器启动以来的表打开操作数:

mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 2741  |
+---------------+-------+

如果该值非常大或增加很快,即使您没有发出很多FLUSH TABLES语句,请 table_open_cache在服务器启动时增加该值。