Mysql 处理大型MyISAM表进行优化
我有一个巨大的(且不断增长的)MyISAM表(700000000行=140Gb) 表格选项已更改为“行\格式=固定”,因为两列的长度始终固定为最大值(60)。是的,Mysql 处理大型MyISAM表进行优化,mysql,database,optimization,partitioning,myisam,Mysql,Database,Optimization,Partitioning,Myisam,我有一个巨大的(且不断增长的)MyISAM表(700000000行=140Gb) 表格选项已更改为“行\格式=固定”,因为两列的长度始终固定为最大值(60)。是的,ID是字符串,而不是INT SELECT查询的速度和效率非常好 数据库和mysql引擎都是127.0.0.1/localhost。(毫不遥远) 遗憾的是,INSERT速度太慢了。我甚至都不想尝试加载数据数百万新行。。。需要几天的时间 不会有任何并发读取。所有选择仅由我的本地服务器一个接一个地完成。(不供客户端使用) (对于信息:文件大
ID
是字符串,而不是INT
SELECT
查询的速度和效率非常好
数据库和mysql引擎都是127.0.0.1/localhost
。(毫不遥远)
遗憾的是,INSERT
速度太慢了。我甚至都不想尝试加载数据
数百万新行。。。需要几天的时间
不会有任何并发读取。所有选择仅由我的本地服务器一个接一个地完成。(不供客户端使用)
(对于信息:文件大小.MYD=88Gb、.MYI=53Gb、.TMM=400Mb)
- 我怎样才能加快插入表的速度
- 对那张巨大的表进行分区会有帮助吗?(那怎么办?
- 我听说MyISAM使用“结构缓存”作为.frm文件。在配置文件中添加一行代码有助于mysql将所有的.frm(在分区的情况下)保存在内存中,这也会有帮助吗?实际上,我的.frm文件只有9kb,仅用于7亿行)
- 字符串缩短/压缩功能。。。ID字符串?(与彩虹表的想法相同)即使它降低了允许的唯一ID的最大值,我无论如何也不会达到60个字符的最大值。也许这是个主意?但在创建新的唯一ID之前,我必须检查db ofc中是否不存在缩短的字符串
- 与缩短ID字符串的想法相同,对ID使用md5()怎么样?在这种情况下,缩短字符串是否意味着更快?
- 添加自动递增数字键并将其设置为主-然后,索引将被聚集,插入的成本将显著降低
- 将当前键转换为二级索引
3) 如果可以的话-首先很明显,您的主键是不可递增的。 这大致意味着:每次插入都必须重新平衡索引 难怪它在这么大的桌子上慢下来。 这样的引擎 那么,第二个问题是:保留MyISAM的旧垃圾有什么意义 比如说,如果发生事故,你不介意松开一排或两排(或十几岁)的绳子吗?等等,等等,等等,等等,甚至抛开当前的MySQL维护者(Oracle Corp.)也明确地不鼓励使用MyISAM 因此,以下是可能的解决方案: 1) 切换到Inno 2) 如果您无法放弃字符ID,则:
- 添加自动递增数字键并将其设置为主-然后,索引将被聚集,插入的成本将显著降低
- 将当前键转换为二级索引
3) 如果可以,很明显,优化表需要针对特定查询进行优化。除非考虑到特定的查询,否则无法确定最佳优化策略。任何优化都会以牺牲其他类型的查询为代价改进一种类型的查询 例如,如果您的查询是
selectsum(pair)FROM keypairs
(一个无论如何都必须扫描整个表的查询),分区将没有帮助,只会增加开销
如果我们假设您的典型查询是通过主键一次插入或选择一个密钥对,那么分区会有很大帮助。这完全取决于优化器是否能够判断查询将在一个狭窄的分区子集(理想情况下是一个分区)中找到其数据
还要确保调整MyISAM。调整选项不多:
- 分配
尽可能高的空间来缓存索引。虽然我从未尝试过任何高于10GB的东西,但我不能保证MyISAM密钥缓冲区稳定在53GB(您的MYI文件大小)key\u buffer\u size
- 预加载密钥缓冲区:
- 大小
和read\u buffer\u Size
根据您运行的查询进行适当调整。我不能在这里给出一个具体的值,你应该用你的查询测试不同的值read\u buffer\u Size
- 如果要加速加载数据填充,请将大小
设置为较大的值。默认为8MB,我会尝试至少256MB。我还没有尝试过这种设置,所以我不能凭经验说话bulk\u insert\u buffer\u Size
是的,请参见我对的回答优化表需要针对特定查询进行优化。除非考虑到特定的查询,否则无法确定最佳优化策略。任何优化都会以牺牲其他类型的查询为代价改进一种类型的查询 例如,如果您的查询是
selectsum(pair)FROM keypairs
(一个无论如何都必须扫描整个表的查询),分区将没有帮助,只会增加开销
如果我们假设您的典型查询是通过主键一次插入或选择一个密钥对,那么分区会有很大帮助。这完全取决于优化器是否能够判断查询将在一个狭窄的分区子集(理想情况下是一个分区)中找到其数据
还要确保调整MyISAM。调整选项不多:
CREATE TABLE `keypairs` ( `ID` char(60) NOT NULL, `pair` char(60) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM
CREATE TABLE new ( ID BINARY(30) NOT NULL, `pair` char(60) NOT NULL -- adding the PK later is faster for MyISAM ) ENGINE=MyISAM; INSERT INTO new SELECT UNHEX(ID), pair FROM keypairs; ALTER TABLE keypairs ADD PRIMARY KEY (`ID`); -- For InnoDB, I would do differently RENAME TABLE keypairs TO old, new TO keypairs; DROP TABLE old;