【问题标题】:skip copying to tmp table on disk mysql跳过复制到磁盘 mysql 上的 tmp 表
【发布时间】:2011-09-23 16:48:23
【问题描述】:

我有一个关于大型 mysql 查询的问题。是否可以跳过 mysql 用于大型查询的 复制到磁盘上的 tmp 表 步骤,或者是否可以使其更快?因为此步骤花费的时间太长,无法恢复我的查询结果。我在 MySQL 页面上读到 mysql 执行此操作以节省内存,但我不关心节省内存我只想快速获取查询结果,我的机器上有足够的内存。此外,我的表已正确编入索引,因此这不是我的查询速度慢的原因。

有什么帮助吗?

谢谢

【问题讨论】:

  • 我不是 MySql 专家,但您最好还是优化查询和/或架构。
  • 我投票结束这个“不是一个真正的问题”。问题不包括要优化的 SQL 查询,也不包括显示哪些索引的 SHOW CREATE TABLE,也不包括显示当前优化计划的 EXPLAIN 报告。
  • 我必须同意@Bill Karwin 的观点,即需要查看查询、创建表语句和/或 EXPLAIN 计划。我的回答将解决您看到的问题,但允许错误查询使 RAM 膨胀。了解查询的性质可能会消除重新配置 RAM 或 mysql 的需要。
  • @close voters,请看看这个问题的真棒答案,并考虑这个问题可能给 SO 带来了多少访问者。投票保持开放

标签: mysql sql


【解决方案1】:

您可以做两件事来减轻这种影响

选项#1:增加变量tmp_table_size和/或max_heap_table_size

这些选项将控制内存中的临时表在被认为太大之前可以有多大,然后作为临时 MyISAM 表分页到磁盘。这些值越大,“复制到磁盘上的 tmp 表”的可能性就越小。请确保您的服务器有足够的 RAM,并且如果单个数据库连接需要大量 RAM 用于其自己的临时表,则 max_connections 已适度配置。

选项 #2:为 tmp 表使用 RAM 磁盘

您应该可以在 Linux 中配置 RAM 磁盘,然后将 mysql 中的tmpdir 设置为安装 RAM 磁盘的文件夹。

对于初学者,请在操作系统中配置 RAM 磁盘

在 Linux 中创建一个名为 /var/tmpfs 的文件夹

mkdir /var/tmpfs

接下来,将此行添加到 /etc/fstab(例如,如果您想要 16GB 的 RAM 磁盘)

none                    /var/tmpfs              tmpfs   defaults,size=16g        1 2

然后重启服务器。

注意:无需重新启动即可制作 RAM 磁盘。请记住,在服务器重启后仍将上述行添加到 /etc/fstab 以获得 RAM 磁盘。

现在是 MySQL:

在 /etc/my.cnf 中添加这一行

[mysqld]
tmpdir=/var/tmpfs

然后重启mysql。

选项 #3:尽快将 tmp 表放入 RAM 磁盘(假设您先应用选项 #2)

您可能希望尽快将 tmp 表强制到 RAM 磁盘中,这样 MySQL 就不会将大型内存中的 tmp 表迁移到 RAM 磁盘中。只需将其添加到 /etc/my.cnf:

[mysqld]
tmpdir=/var/tmpfs
tmp_table_size=2K

然后重启mysql。这将导致即使是最小的临时表也直接存在于 RAM 磁盘中。您可以定期运行ls -l /var/tmpfs 来观察临时表的来来去去。

试试看!!!

警告

如果您在 /var/tmpfs 24/7 中只看到临时表,这可能会影响操作系统的功能/性能。为确保 /var/tmpfs 不会过度填充,请考虑调整您的查询。完成后,您应该会在 /var/tmpfs 中看到更少的 tmp 表。

【讨论】:

  • 如果你在 linux (特别是 ubuntu) 上,还有几点你可能需要在 (/etc/apparmor.d/usr.sbin.mysqld) 中添加你的 tmpdir 路径到应用程序装甲也不要忘记到 chmod 777 目录也是如此!
  • 当我在 ubuntu 灯服务器上尝试此操作时,当我尝试重新启动 mysql 时,我的作业无法启动。然后我将它切换回默认的 /tmp 并且它开始正常。 @Dan 你能举个例子来说明你添加到 user.sbin.mysqld 的那个位吗?谢谢
  • 仅供参考,除了添加/etc/apparmor.d/usr/sbin.mysqld之外,我还必须在ubuntu上执行以下操作,我必须添加到/etc/apparmor.d/abstractions/user -tmp 也以与原始 tmp 文件夹相同的格式添加。
  • 运行ls -l 时看不到文件。我读过mysql创建文件rm's它然后写入它在它是rm'd之后。是这样吗?使用此策略时,写入临时表的查询没有提高性能。我还有大约 5 秒的时间“复制到磁盘上的 tmp 表”。如何验证我的设置?
  • 如何知道mysql需要的tmpfs目录的大小?什么大小的mysql去使用tempdir?
【解决方案2】:

您也可以跳过复制到磁盘上部分的tmp表(未在所选答案中回答)

  1. 如果您避免使用某些数据类型:

支持 MEMORY 不支持的可变长度数据类型(包括 BLOB 和 TEXT)。

来自https://dev.mysql.com/doc/refman/8.0/en/memory-storage-engine.html (或https://mariadb.com/kb/en/library/memory-storage-engine/,如果您使用的是 mariadb)。

  1. 如果您的临时表足够小:如所选答案中所述,您可以

    增加变量 tmp_table_size 和/或 max_heap_table_size

但是,如果您将查询拆分为较小的查询(没有查询无助于分析您的问题),您可以使其适合内存临时表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2013-12-03
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多