MySQL没有完全利用服务器

时间:2016-02-26 10:59:28

标签: mysql database performance amazon-web-services amazon-rds

我在Amazon RDS db.m4.xlarge(16Gb RAM,4vCPU)多区域部署上运行MariaDB 10.0.17。我们使用最大设置为10000 IOPS的预配置IOPS存储。 users表包含17M条记录; user_properties表包含350M条记录。

user_properties表描述了附加到用户的道具的“地图”。 upkey是关键,string_valueinteger_value等是每种类型的值; STRING,DATE,INTEGER,DOUBLE。索引也是每种类型。

我们尝试向user_properties表插入更多数据:应用程序将数据插入INNODB临时表TEMP1,然后将数据从TEMP1复制到user_properties表。

问题是我们只能达到2500写入IOPS和500-1000读取IOPS。队列深度平均保持在~7左右。 MySQL服务器CPU使用率保持在20-30%,从未达到60%。 应用程序似乎向MySQL提供了足够的数据:我们将类似的数据文件提供给数据库,并查看处理时间随着表大小的增加而增加。 大部分时间应用程序等待MySQL查询完成。在此过程中,插入TEMP1表只占总时间的一小部分,大部分时间都在等待从TEMP1表插入user_properties

有人可以帮助我加快MySQL速度吗?我应该增加/改变什么?

CREATE TABLE IF NOT EXISTS `users` (
  `id` bigint(20), // Column is not used now. Filled with NULL
  `version` bigint(20) NOT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `uuid` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
  `partner_id` bigint(20) NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `date_created` datetime DEFAULT NULL,
  `last_updated` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique-email` (`partner_id`,`email`),
  UNIQUE KEY `users_Uuid` (`uuid`),
  KEY `idx_013_partner_id_uuid` (`partner_id`,`uuid`),
  KEY `idx_014_uuid` (`uuid`),
  CONSTRAINT `FKB2D9FEBE725C505E` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`),
  CONSTRAINT `fk_046_partner` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


CREATE TABLE IF NOT EXISTS `user_properties` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` bigint(20) NOT NULL,
  `date_created` datetime DEFAULT NULL,
  `last_updated` datetime DEFAULT NULL,
  `upkey` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `user_id` bigint(20) DEFAULT NULL,
  `security_level` int(11) NOT NULL,
  `_content` longtext COLLATE utf8_unicode_ci NOT NULL,
  `class` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `date_value` datetime DEFAULT NULL,
  `integer_value` bigint(20) DEFAULT NULL,
  `double_value` double DEFAULT NULL,
  `string_value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `uuid` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_004_uuid` (`uuid`),
  KEY `idx_005_string_value` (`upkey`,`string_value`),
  KEY `idx_006_integer_value` (`upkey`,`integer_value`),
  KEY `idx_007_double_value` (`upkey`,`double_value`),
  KEY `idx_008_date_value` (`upkey`,`date_value`),
  KEY `idx_key_value_user_upkey_string` (`user_id`,`upkey`,`string_value`),
  CONSTRAINT `FK_users` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

1 个答案:

答案 0 :(得分:2)

您是否需要iduuid?我想不是。

桌子需要3个UNIQUE个键吗?我想不是。 (请记住,PRIMARY KEYUNIQUE。)

当表变大时,

uuid有一些非常糟糕的I / O属性。重新考虑你对它们的使用。 uuid上的索引非常随机。当索引(或表)变得太大而无法放入buffer_pool时,提取往往涉及I / O而不是缓存。有350M行和16GB RAM,我怀疑性能问题的很大一部分是由于uuids。

user_properties是一个“键值”商店,对吗?架构设计模式很糟糕。什么是典型的SELECT?我怀疑它是这样的:

SELECT ..._value FROM user_properties
    WHERE user_id = '...'
      AND upkey = '...';

假设这是正确的,可以通过

来改善性能
PRIMARY KEY(user_id, upkey, id)

这将在一个位置(大概1-2个块)“聚集”给定用户的键值对,从而使他们的提取更快。

有关evils of key-value的更多内容以及改进建议 有关evils of UUIDs的更多信息。