Mysql 处理大型MyISAM表进行优化

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速度太慢了。我甚至都不想尝试加载数据数百万新行。。。需要几天的时间 不会有任何并发读取。所有选择仅由我的本地服务器一个接一个地完成。(不供客户端使用) (对于信息:文件大

我有一个巨大的(且不断增长的)MyISAM表(700000000行=140Gb)

表格选项已更改为“行\格式=固定”,因为两列的长度始终固定为最大值(60)。是的,
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()怎么样?在这种情况下,缩短字符串是否意味着更快?

首先,您的主键不可递增。 这大致意味着:每次插入都必须重新平衡索引

难怪它在这么大的桌子上慢下来。 这样的引擎

那么,第二个问题是:保留MyISAM的旧垃圾有什么意义

比如说,如果发生事故,你不介意松开一排或两排(或十几岁)的绳子吗?等等,等等,等等,等等,甚至抛开当前的MySQL维护者(Oracle Corp.)也明确地不鼓励使用MyISAM

因此,以下是可能的解决方案:

1) 切换到Inno

2) 如果您无法放弃字符ID,则:

  • 添加自动递增数字键并将其设置为主-然后,索引将被聚集,插入的成本将显著降低

  • 将当前键转换为二级索引


3) 如果可以的话-首先很明显,您的主键是不可递增的。 这大致意味着:每次插入都必须重新平衡索引

难怪它在这么大的桌子上慢下来。 这样的引擎

那么,第二个问题是:保留MyISAM的旧垃圾有什么意义

比如说,如果发生事故,你不介意松开一排或两排(或十几岁)的绳子吗?等等,等等,等等,等等,甚至抛开当前的MySQL维护者(Oracle Corp.)也明确地不鼓励使用MyISAM

因此,以下是可能的解决方案:

1) 切换到Inno

2) 如果您无法放弃字符ID,则:

  • 添加自动递增数字键并将其设置为主-然后,索引将被聚集,插入的成本将显著降低

  • 将当前键转换为二级索引


3) 如果可以,很明显,优化表需要针对特定查询进行优化。除非考虑到特定的查询,否则无法确定最佳优化策略。任何优化都会以牺牲其他类型的查询为代价改进一种类型的查询

例如,如果您的查询是
selectsum(pair)FROM keypairs
(一个无论如何都必须扫描整个表的查询),分区将没有帮助,只会增加开销

如果我们假设您的典型查询是通过主键一次插入或选择一个密钥对,那么分区会有很大帮助。这完全取决于优化器是否能够判断查询将在一个狭窄的分区子集(理想情况下是一个分区)中找到其数据

还要确保调整MyISAM。调整选项不多:

  • 分配
    key\u buffer\u size
    尽可能高的空间来缓存索引。虽然我从未尝试过任何高于10GB的东西,但我不能保证MyISAM密钥缓冲区稳定在53GB(您的MYI文件大小)
  • 预加载密钥缓冲区:
  • 大小
    read\u buffer\u Size
    read\u buffer\u Size
    根据您运行的查询进行适当调整。我不能在这里给出一个具体的值,你应该用你的查询测试不同的值
  • 如果要加速加载数据填充,请将大小
    bulk\u insert\u buffer\u Size
    设置为较大的值。默认为8MB,我会尝试至少256MB。我还没有尝试过这种设置,所以我不能凭经验说话
我尽量不使用MyISAM。MySQL肯定是在极力反对它的使用

…是否有mysql命令自动更改TABLE add INT ID增量列


是的,请参见我对

的回答优化表需要针对特定查询进行优化。除非考虑到特定的查询,否则无法确定最佳优化策略。任何优化都会以牺牲其他类型的查询为代价改进一种类型的查询

例如,如果您的查询是
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;