Mysql InnoDB唯一约束降低插入速度

Mysql InnoDB唯一约束降低插入速度,mysql,performance,insert,innodb,unique-constraint,Mysql,Performance,Insert,Innodb,Unique Constraint,嘿,伙计们,我一直在努力解决Innodb中的一个问题。我正在设计的数据库是为容纳.com和.net下列出的所有域而构建的。我每周从一个文件中读取这些数据,然后将它们输入数据库。正如你可以猜到的,将会有很多记录。我现在已经计算出接近1.06亿个.coms和1400万个.net(估计值),为了防止域的重复记录,我在域名列上设置了一个唯一的约束,并设置了第二个TLDid。每当我每周更新时,插入需要5-6天。在没有数据的初始构建中,我得到了正常的插入速度,直到我以2500万开始插入,然后它真的开始变慢

嘿,伙计们,我一直在努力解决Innodb中的一个问题。我正在设计的数据库是为容纳.com和.net下列出的所有域而构建的。我每周从一个文件中读取这些数据,然后将它们输入数据库。正如你可以猜到的,将会有很多记录。我现在已经计算出接近1.06亿个.coms和1400万个.net(估计值),为了防止域的重复记录,我在域名列上设置了一个唯一的约束,并设置了第二个TLDid。每当我每周更新时,插入需要5-6天。在没有数据的初始构建中,我得到了正常的插入速度,直到我以2500万开始插入,然后它真的开始变慢

我改变了我的innodb\u缓冲池\u池大小=6000M,没有太多变化。我可以插入多达4500万次,然后在3小时左右开始变慢

我已经阅读了很多关于性能的文章,并更改了更多设置:

innodb_线程_并发=18

innodb\u锁定\u等待\u超时=50

innodb_文件每_表=1

innodb_read_io_threads=3000(默认为64)

innodb_write_io_threads=7000(默认为64)

innodb_io_容量=10000

innodb_刷新_日志_在_trx_commit=2

我的插入速度仍然很慢:

下面是该表的外观:

    -- Dumping structure for table domains.domains
    CREATE TABLE IF NOT EXISTS `domains` (
      `DomainID` bigint(19) unsigned NOT NULL AUTO_INCREMENT,
      `DomainName` varchar(100) DEFAULT NULL,
      `TLDid` int(5) unsigned DEFAULT '1',
      `FirstSeen` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
      `LastUpdated` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`DomainID`),
      UNIQUE KEY `UNIQUE DOMAIN INDEX` (`TLDid`,`DomainName`),
      KEY `TIMESTAMP INDEX` (`LastUpdated`,`FirstSeen`),
      KEY `TLD INDEX` (`TLDid`),
      KEY `DOMAIN NAME INDEX` (`DomainName`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
TLDid是1或2,但它将表示域的扩展,例如“Test.com”将存储为DomainName:Test TLDid 1。“Test.net”将存储为域名:Test TLDid:2

我的问题是,如何使用1.3亿条以上的记录优化此表,并在插入之前检查两个唯一的约束,以使更新新记录和当前记录不会减慢表的速度


谢谢各位

您有一个重复的索引-
TLD索引
是不必要的,因为该字段已经被
唯一域索引
作为该键的第一个字段索引。对于您所说的大小的大容量插入,禁用索引、执行插入(重复和全部)、重新启用索引,然后清除重复可能会更快。
TLDid
列作为
ENUM('.com','.net')
可能会更好。通过这种方式,您可以将其作为一个整数来处理,但MySQL“知道”它们的含义,因此您可以更轻松地进行连接以获得全名。它还将每行仅使用1个字节,而不是当前的
INT
列每行使用4个字节。另一件事:您是否检查了在查询运行时使用了多少InnoDB缓冲区?我的猜测是缓冲区溢出了,并且必须在内存和磁盘之间不断地移动。如果是这样的话,那将导致严重的性能问题,就像你现在遇到的一样。马克,我不知道你能做到这一点。谢谢你的主意。谢谢掘金,我也会加上的。我相信你是对的。在执行插入时,mysql加载所有唯一约束,并在插入之前检查它们。因此,一旦达到某个点,内存将无法保存所有唯一的约束,并且速度会大大降低。@G-Nugget使用
ENUM
作为
TLDid
的值可能是一个非常糟糕的主意。最好将它们规范化存储在一个表中,并由ID引用。如果使用
ENUM
,则每增加一个TLD,就必须
ALTER
该表,这将非常昂贵。