为什么 mysql 的打开表和碎片表比数据库中的表多得多?

为什么 mysql 的打开表和碎片表比数据库中的表多得多?

过去一周,我一直在努力让我们的数据库运行得更顺畅,并取得了不错的成果。但仍然有些事情我不明白。

首先,数据库有 25 个表。但 mysql 状态显示有 512 个表处于打开状态:mysqladmin status 正常运行时间:212854 线程:1 问题:43041 慢查询:7 打开:2605 刷新表:1 打开表:512 每秒查询平均值:0.202

我读过 isam 打开了额外的文件描述符,还有其他一些原因导致打开的表数可能高于 25,但我猜 512 不是一件好事。有什么建议可以解释为什么会这样,或者我应该调查什么?

我也一直在使用 mysqltuner,它很有用。但它始终将碎片表的数量列为 207。在 phpmyadmin 中,我选择了所有表并对其进行了多次优化。它并没有减少 mysqltuner 报告的碎片表数量。

我觉得我遗漏了一些关于这一切如何运作的重要概念。有没有人能给我一些建议,为我指明正确的方向,或者缩小谷歌搜索的范围,或者只是帮助我减少无知?

谢谢!

-------- 一般统计数据 --------------------------------------------------
[--] 跳过 MySQLTuner 脚本的版本检查
[确定] 当前正在运行支持的 MySQL 版本 5.5.20-log
[OK] 在 64 位架构上运行

-------- 存储引擎统计 ----------------------------------------------------------
[--] 状态:+存档-BDB-Federated+InnoDB-ISAM-NDBCluster
[--] MyISAM 表中的数据:1M(表:254)
[--] InnoDB 表中的数据:3M(表:199)
[--] PERFORMANCE_SCHEMA 表中的数据:0B(表:17)
[!!] 碎片表总数:200

-------- 安全建议 ----------------------------------------------------------
[确定] 所有数据库用户都已分配密码

-  -  -  -  性能指标  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - -
[--] 持续时间:3 天 12 小时 5 分 8 秒(142K q [0.472 qps],11K conn,TX:105M,RX:37M)
[--] 读取/写入:79%/21%
[--] 总缓冲区:全局 202.0M + 每个线程 2.5M(最多 100 个线程)
[确定] 最大可能的内存使用量:452.0M(已安装 RAM 的 48%)
[OK] 慢速查询:0% (8/142K)
[OK] 可用连接的最高使用率:9% (9/100)
[确定] 键缓冲区大小/总 MyISAM 索引:16.0M/741.0K
[OK] 密钥缓冲区命中率:99.9% (404K 缓存/513 次读取)
[OK] 查询缓存效率:72.1%(61K 缓存/84K 选择)
[确定] 每日查询缓存修剪次数:0
[OK] 需要临时表的排序:0% (0 临时排序/1K 排序)
[!!] 磁盘上创建的临时表:41%(磁盘上 6K/总共 14K)
[OK] 线程缓存命中率:99%(创建 9 个/11K 个连接)
[!!] 表缓存命中率:15%(512打开/3K打开)
[确定] 使用的打开文件限制:55% (633/1K)
[OK] 立即获取表锁:100% (40K 立即/40K 锁)
[!!] 连接中止:7%
[确定] InnoDB 数据大小/缓冲池:3.3M/16.0M

-------- 建议 -----------------------------------------------------------------
一般建议:
    运行 OPTIMIZE TABLE 对表进行碎片整理,以获得更好的性能
    进行调整时,使 tmp_table_size/max_heap_table_size 相等
    减少没有 LIMIT 子句的 SELECT DISTINCT 查询
    逐渐增加 table_cache 以避免文件描述符限制
    您的应用程序没有正确关闭 MySQL 连接
需要调整的变量:
    tmp_table_size (> 128M)
    最大堆表大小 (> 128M)
    表缓存 (> 512)

答案1

这可能与table_cache和/或有关max_connections

对于 MyISAM 表,每个新线程/连接都需要打开表。换句话说,如果您有一个表并且有十个客户端访问该表,则根据 MySQL 状态行,您有十个打开的表。通过table_cache保持表对线程保持打开状态,有助于减少不断打开/关闭表的工作。

您的表缓存似乎工作得很好,因为已经有 43 041 个查询,但实际上只需要打开表 2605 次。

InnoDB 有自己的连接池,并且行为略有不同。

有关详细信息,请参阅For more information, seeMySQL 如何打开和关闭表

相关内容