我在Amazon RDS db.m4.xlarge(16Gb RAM,4vCPU)多可用区部署上运行了MariaDB 10.0.17。我们使用预置的IOPS存储,最大设置为10000 IOPS。users
该表包含1700万条记录;user_properties
该表包含350M条记录。
user_properties
表格描述了附加到用户的道具的“地图”。upkey
是关键,string_value
,integer_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;
您是否同时需要id
和uuid
?我想不是。
UNIQUE
一张桌子需要三把钥匙吗?我想不是。(记住aPRIMARY KEY
是UNIQUE
。)
uuid
当表变大时,它具有一些非常差的I / O属性。重新考虑您对它们的使用。上的索引uuid
是很随机的。当索引(或表)变得太大而无法容纳到buffer_pool中时,访存将涉及I / O而不是被缓存。凭借350M行和16GB RAM,我怀疑性能问题的很大一部分归因于uuid。
user_properties
是“键值”存储区吗?该架构设计模式很糟糕。典型的是什么SELECT
?我怀疑是这样的:
SELECT ..._value FROM user_properties
WHERE user_id = '...'
AND upkey = '...';
假设是正确的,则可以通过以下方式提高性能:
PRIMARY KEY(user_id, upkey, id)
这会将给定用户的键值对“聚集”在单个位置(可能是1-2个块),从而使它们的获取更快。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句