【问题标题】:MySQL Exhausting 1.5TB of Disk Space During SortMySQL 在排序期间耗尽了 1.5TB 的磁盘空间
【发布时间】:2010-10-11 17:32:18
【问题描述】:

我有一个包含大约 14 亿条记录的表,格式如下:

mysql> 描述_2009all; +---------------+--------------+------+-----+----- ----+-------+ |领域 |类型 |空 |钥匙 |默认 |额外 | +---------------+--------------+------+-----+----- ----+-------+ |用户名 |整数(11) |是 |穆尔 |空 | | |类型 | varchar(50) |是 | |空 | | |种类 | varchar(50) |是 | |空 | | |描述 | varchar(255) |是 | |空 | | |捆绑版本 | varchar(255) |是 | |空 | | |捆绑ID | varchar(255) |是 | |空 | | |时间 |大整数(20) |是 | |空 | | +---------------+--------------+------+-----+----- ----+-------+ 一组 7 行(0.02 秒)

整个数据库占用不到 0.4 TB,而我有大约 1.5 TB 的可用磁盘空间。

我正在尝试准备用于分析的数据,我会查看每个用户随着时间的推移所做的事情。所以我运行以下语句:

创建表 sorted2009 AS (select * from _2009all order by userid,time);

该语句(显然)需要很长时间才能运行,但在某些时候,它会耗尽所有可用磁盘空间,并且我收到“ERROR 3 (HY000): Error writing file”错误。

关于如何创建排序表的任何想法?提前致谢。

澄清

Martin:只有 1 个分区。

Andy:我要解决的问题是“select * from _2009all order by userid,time”的结果是我将在接下来的几个月中大量检查的结果。因此,我不是每次想要检查结果时都运行这个查询,而是想将结果放在一个表中以便更快地访问。

我最初认为随着时间的推移建立索引会浪费空间,因为时间戳大多是唯一的。但是我只是在_2009all的时间字段中添加了索引,索引占用了合理的空间。但现在要对两个索引进行排序(我假设你的意思是“索引步行”):

mysql> select * from _2009all order by userId,time limit 2; ... 一组 2 行(25 分 36.48 秒)

是的,我会说 25 分钟太长了。但是,如果您的建议是其他意思,我愿意接受替代方案。

bot43:

将索引添加到时间字段后:

mysql> explain select * from _2009all order by userid,time; +----+-------------+----------+------+------------ ---+--------+---------+------+------------+--------- --------+ |编号 |选择类型 |表|类型 |可能的键 |关键 | key_len |参考 |行 |额外 | +----+-------------+----------+------+------------ ---+--------+---------+------+------------+--------- --------+ | 1 |简单 | _2009全部 |全部 |空 |空 |空 |空 | 1384378798 |使用文件排序 | +----+-------------+----------+------+------------ ---+--------+---------+------+------------+--------- --------+ 一组中的 1 行(0.05 秒) mysql> explain select userId,type,kind,description,bundleVersion,bundleId,time from _2009all order by userid,time +----+-------------+----------+------+------------ ---+--------+---------+------+------------+--------- --------+ |编号 |选择类型 |表|类型 |可能的键 |关键 | key_len |参考 |行 |额外 | +----+-------------+----------+------+------------ ---+--------+---------+------+------------+--------- --------+ | 1 |简单 | _2009全部 |全部 |空 |空 |空 |空 | 1384378798 |使用文件排序 | +----+-------------+----------+------+------------ ---+--------+---------+------+------------+--------- --------+ 一组中的 1 行(0.00 秒)

关于 DBMS 以任何该死的方式存储表的优点。我想我需要另一个解决方案。

【问题讨论】:

  • 空闲空间都在同一个磁盘分区吗?您的 tmpdir 变量是否设置为分区中具有所有空间的目录?
  • 'explain select * from _2009all order by userid,time' 显示什么?另外,如果您删除 * 并改用列名怎么办?那解释呢?我已经阅读了 * 可以引导您在查询优化器中使用一些替代路径,可能会否定索引。理想情况下,您可能会在说明中看到“文件排序”选项,并且您希望摆脱它,以便它按照您想要的顺序从磁盘读取数据,而不是创建一个临时表来对其进行排序。但是,即使您在插入数据之前对数据进行了排序,数据库也会存储 sorted2009 但它希望有效地撤消您的排序。
  • 为什么要创建表格的排序版本?您要解决的问题是什么?对您来说,索引表的步行速度是否不够快?

标签: mysql


【解决方案1】:

你的桌子上有什么索引?

你不能在两列上加上composite index吗?

ALTER TABLE `_2009all` ADD INDEX ( `userId` , `time` ) ;

【讨论】:

  • 就可以了。感谢 bot403 和 Andy Lester 的协助。
【解决方案2】:

我认为您不能使用一些技巧来使此操作占用更少的空间。如果那是你要问的。简短而简单的答案是:通过添加另一个硬盘驱动器来获得更多空间。有了这种数据库,无论如何你都需要它。

您也可以尝试将表格分成两个或更多部分,然后一次对每个表格进行排序和查看。如果这对你有用。 GL!

【讨论】:

  • 解决方案不是获取更多磁盘,而是正确使用现有磁盘...索引是解决方案。
  • 我试图回答原来的问题。无法创建排序表以占用更少的空间。他需要排序表是另一个问题。所以,不要告诉我解决方案是什么。这不是解决方案,而是另一种方法。据我们所知,他可能也不需要所有数据:)
猜你喜欢
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 2020-01-20
  • 2020-08-28
  • 2019-12-01
  • 1970-01-01
相关资源
最近更新 更多