在内存中缓存 MySQL 数据库

gra*_*lor 12 mysql performance wordpress

我在使用 600MB 的 MySQL 数据库的网站时遇到问题。网站太慢了。我注意到 MySQL 数据库越大,运行速度就越慢。当它是 5MB 时,网站速度非常快。当它开始变大时,它开始变得越来越慢,现在 600MB,它真的很慢,加载页面需要 10 秒。

我检查了顶级进程,它与高负载或任何事情无关。它甚至与 IOPS 无关,因为我在 HDD 7.2k rpm 驱动器上进行了测试,现在使用 Intel 320 SSD 驱动器进行测试时出现了同样的问题,因此我认为这也与高查询无关。

该网站正在使用 Wordpress,并且有 9 个插件处于活动状态。人们说这可能是插件......好吧也许......但现在我只想将整个数据库缓存在内存中,并希望获得有关从哪里开始以及如何做的帮助和指导。

我有 16GB RAM 和 i5-2400 4 核 @ 3.1 GHz。操作系统是centos 5.7

top - 07:23:57 up 9 days, 12:15, 0 users, load average: 0.09, 0.04, 0.05
Tasks: 162 total, 1 running, 161 sleeping, 0 stopped, 0 zombie
Cpu(s): 8.2%us, 1.0%sy, 0.0%ni, 90.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 16367532k total, 3641628k used, 12725904k free, 612140k buffers
Swap: 1046520k total, 0k used, 1046520k free, 1538896k cached
Run Code Online (Sandbox Code Playgroud)

Rol*_*DBA 11

如果我是你,我会将所有数据切换到 InnoDB。许多人长期以来一直在讨论表锁定/行锁定。我总是会毫不犹豫地选择 InnoDB。然而,选择 InnoDB...CACHING 还有另一个深刻的原因

虽然大多数人吹嘘 MyISAM 读取速度更快,但大多数人忘记了 MyISAM 的许多缓存,称为键缓存(由 key_buffer_size 设置),只缓存来自 .MYI 文件的索引页。它从不缓存数据页。它在 32 位系统中的官方最大容量为 4GB。8GB 是 64 位的最佳最大值。

InnoDB 缓冲池缓存数据和索引页。根据您拥有的服务器,您可以在 RAM 中缓存整个数据集。您可以将 InnoDB 调整为最多 80% 的 RAM 和 10% 的 DB Conenctions,并为 OS 保留 10%。即使对于不同的操作系统也是如此

我已经向 Drupal 客户推荐了这些东西,并取得了巨大的成功。它同样适用于 Wordpress。我已经为使用 WordPress 的客户提供了数据库支持。同样的改进。

你总是可以更有效地为 InnoDB 配置内存,而不是更多的 MyISAM。总有一种方法可以调整 InnoDB 以满足您的性能需求。随着数据的增长,它最终将成为一种需求

更新 2011-11-21 11:44 EST

如果您的完整数据集足够小,您可以在 mysql 启动后立即对您拥有的每个表执行 SELECT 查询。

对于 InnoDB 和/或 MyISAM 的所有表,运行以下查询:

SELECT DISTINCT
    CONCAT('SELECT ',ndxcollist,' FROM ',
    db,'.',tb,' ORDER BY ',ndxcollist,';') SelectQueryToLoadCache
FROM (
    SELECT
        engine,table_schema db,table_name tb,index_name,
        GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist
    FROM (
        SELECT
            B.engine,A.table_schema,A.table_name,
            A.index_name,A.column_name,A.seq_in_index
        FROM
            information_schema.statistics A INNER JOIN
            (SELECT engine,table_schema,table_name
            FROM information_schema.tables
            WHERE engine IN ('InnoDB','MyISAM')) B
            USING (table_schema,table_name)
        WHERE
            B.table_schema NOT IN ('information_schema','mysql')
            AND A.index_type <> 'FULLTEXT'
        ORDER BY
            table_schema,table_name,index_name,seq_in_index
        ) A
    GROUP BY
        table_schema,table_name,index_name
) AA
ORDER BY
    engine DESC,db,tb
;
Run Code Online (Sandbox Code Playgroud)

这将输出您需要运行的每个可能的 SELECT 查询,这些查询将调用所有要引用的索引。将此查询放在名为 /root/MakeSelectQueriesToLoad.sql 的文件中。运行脚本并收集输出 /root/SelectQueriesToLoad.sql。最后,运行它:

mysql -u... -p... -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql
mysql -u... -p... < /root/SelectQueriesToLoad.sql
Run Code Online (Sandbox Code Playgroud)

这肯定会将所有索引页预加载到 InnoDB 缓冲池和 MyISAM 密钥缓存中。如果您的所有数据都是 InnoDB,请进行两项更改:

  • 替换WHERE engine IN ('InnoDB','MyISAM')WHERE engine='InnoDB'
  • 替换CONCAT('SELECT ',ndxcollist,' FROM ',CONCAT('SELECT * FROM ',

这也会将更多数据页填充到 InnoDB 缓冲池中。

最后注意事项:确保 InnoDB 缓冲池足够大以容纳所有 InnoDB 数据


小智 3

您已经将整个数据库缓存在内存中。几乎可以肯定,问题在于搜索数据库所需的时间,即使在 RAM 中也是如此。

查看磁盘 I/O 统计信息。您可能会发现只是偶尔出现随机的磁盘 I/O 位。数据库内存中。那不是问题。您需要iostat先安装。您没有提及您的平台或发行版,但它可能位于名为 的包中iostat。你可能会发现atop更加友好。

告诉你这件事的人是否是在得到任何证据表明你的整个数据库不在内存中或者磁盘 I/O 是问题之后才这么做的?否则,他们的建议就相当于一位医生从未见过或检查过你,只是听说你的手臂受伤,告诉你打石膏。