【发布时间】: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