MySql表性能优化-哈希作为主键或唯一键

时间:2018-09-11 00:56:42

标签: mysql mariadb

更新* : 看完我的Python脚本后,我发现在插入记录之前准备和计算数据是发生处理时间最多的地方,而不是数据库插入。插入实际上相对较快(表大小为1,000,000条记录的10,000条记录大约需要30秒)。但是,我确实认为我对这个问题的反馈也将帮助我优化刀片。感谢所有答复。现在,我开始尝试优化Python脚本以加快速度。

我目前有一个具有以下结构的MariaDB表:

CREATE TABLE IF NOT EXISTS `adeck_errors` (
  `StormID` varchar(8) NOT NULL DEFAULT '1',
  `ModelBaseTime` datetime NOT NULL,
  `Model` varchar(4) NOT NULL,
  `Tau` smallint(4) NOT NULL,
  `LatCARQ` float DEFAULT NULL,
  `LonCARQ` float DEFAULT NULL,
  `LatModel` float DEFAULT NULL,
  `LonModel` float DEFAULT NULL,
  `DistError` smallint(6) DEFAULT NULL,
  `WindCARQ` int(11) DEFAULT NULL,
  `WindModel` int(11) DEFAULT NULL,
  `WindError` smallint(6) DEFAULT NULL,
  `PresCARQ` int(11) DEFAULT NULL,
  `PresModel` int(11) DEFAULT NULL,
  `PresError` smallint(6) DEFAULT NULL,
  UNIQUE KEY `StormID` (`StormID`,`ModelBaseTime`,`Model`,`Tau`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

如您所见,我的唯一键跨越表中的4个字段,以确保我没有任何重复的条目。当我在已经包含100万条记录的表中插入10,000条以上的记录时,这大约需要15-20分钟,我想加快这一过程。

我的问题是,最好在4个字段中创建数据的哈希并将该哈希用作主键,这样我就不会重复吗?在插入之前(使用Python)处理数据时,可以在进入DB Insert函数之前快速创建4个数据的哈希值。

感谢您的建议。 布莱恩

2 个答案:

答案 0 :(得分:0)

当前,您没有“适当”或“正常”主键。这是相关的,因为主键用作所谓的clustered index来排序磁盘上的行。 InnoDB将选择下一个合适的键作为聚簇索引的候选:

  
      
  • 如果您没有为表定义PRIMARY KEY,MySQL会找到第一个UNIQUE索引,其中所有键列都是NOT NULL,InnoDB会将其用作聚集索引。
  • li>   

在您的情况下,它是唯一存在的UNIQUE KEY "StormId"。您的行通过此键在磁盘上排序,现在您遇到与使用GUID / UUID作为主键相同的问题。当您阅读诸如The differences between int and uuid in mysqlhttp://kccoder.com/mysql/uuid-vs-int-insert-performance/https://www.percona.com/blog/2007/03/13/to-uuid-or-not-to-uuid/之类的问题和文章时,您会发现不应使用这样的键对磁盘上的行进行排序。

创建普通的BIGINT AUTO_INCREMENT PRIMARY KEY列以获得更好的性能。

答案 1 :(得分:0)

  • UNIQUE键更改为PRIMARY。这可能不会产生任何影响,但是,它将使您的意图更加清晰。
  • 重复数据删除应该很好。
  • 为获得更好的性能,请在开始加载之前根据PK对传入数据进行排序。
  • 您如何加载?如果您在csv文件中接收到数据,则LOAD DATA最好,多行INSERTs最好。一次一排最慢。
  • UUID确实会降低性能;不要这样做。
  • innodb_buffer_pool_size应该是可用RAM的大约70%。