【问题标题】:Aurora MySQL reader performance degrades over timeAurora MySQL 读取器性能会随着时间的推移而降低
【发布时间】:2021-07-17 04:32:23
【问题描述】:

我有一个 Aurora MySQL 集群,当对阅读器运行查询时,我发现性能会随着时间的推移而下降。重新启动读取器会导致查询性能与写入器匹配。但是在一周没有重启的情况下,查询的运行时间是原来的 25 倍。

读取器实例的复制延迟为 20 毫秒,并且没有任何监控指标显示问题。我见过的CPU最高是40%。我尝试了将 block_nested_loop 设置为 off 的建议,但没有效果。

阅读器没有太多活动,因此负载应该不是问题。我们确实需要对它运行一个复杂的查询,该查询会返回大量用于分析的数据。我发现返回由索引检索的少量记录的查询没有性能问题。但是类似的查询返回同样少的记录并且需要进行表扫描,确实存在性能问题。

降级速度似乎是一致的,因此这似乎是与复制相关的资源问题,但我没有任何运气在网上找到任何记录该问题的内容。

任何帮助将不胜感激。

更新:更多详情

查询执行计划

-- Fast query
explain select cpv.SHORT_TEXT_VALUE, c.UIDPK, c.GUID, c.SHARED_ID, cpv.* 
from TCUSTOMERPROFILEVALUE cpv 
inner join TCUSTOMER c on cpv.CUSTOMER_UID = c.UIDPK
where LOCALIZED_ATTRIBUTE_KEY = 'CP_EMAIL' and cpv.SHORT_TEXT_VALUE = 'some-email@gmail.com';

-- Slow query, using function to prevent use of index for email match
explain select cpv.SHORT_TEXT_VALUE, c.UIDPK, c.GUID, c.SHARED_ID, cpv.* 
from TCUSTOMERPROFILEVALUE cpv 
inner join TCUSTOMER c on cpv.CUSTOMER_UID = c.UIDPK
where LOCALIZED_ATTRIBUTE_KEY = 'CP_EMAIL' and LOWER(cpv.SHORT_TEXT_VALUE) = 'some-email@gmail.com';

表定义

CREATE TABLE `TCUSTOMERPROFILEVALUE` (
  `UIDPK` bigint(20) NOT NULL,
  `ATTRIBUTE_UID` bigint(20) NOT NULL,
  `ATTRIBUTE_TYPE` int(11) NOT NULL,
  `LOCALIZED_ATTRIBUTE_KEY` varchar(255) NOT NULL,
  `SHORT_TEXT_VALUE` varchar(255) DEFAULT NULL,
  `LONG_TEXT_VALUE` mediumtext,
  `INTEGER_VALUE` int(11) DEFAULT NULL,
  `DECIMAL_VALUE` decimal(19,2) DEFAULT NULL,
  `BOOLEAN_VALUE` int(11) DEFAULT '0',
  `DATE_VALUE` datetime DEFAULT NULL,
  `CUSTOMER_UID` bigint(20) DEFAULT NULL,
  `LAST_MODIFIED_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `CREATION_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`UIDPK`),
  KEY `I_CPV_ATTR_UID` (`ATTRIBUTE_UID`),
  KEY `I_CPV_CUID_ATTKEY` (`CUSTOMER_UID`,`LOCALIZED_ATTRIBUTE_KEY`),
  KEY `I_CPV_STV_ATTVALUE` (`SHORT_TEXT_VALUE`),
  KEY `I_CPV_ATTKEY_SHORTTEXT` (`LOCALIZED_ATTRIBUTE_KEY`,`SHORT_TEXT_VALUE`),
  CONSTRAINT `FK_PROFILE_CUSTOMER` FOREIGN KEY (`CUSTOMER_UID`) REFERENCES `TCUSTOMER` (`UIDPK`) ON DELETE CASCADE,
  CONSTRAINT `TCUSTOMERPROFILEVALUE_FK_1` FOREIGN KEY (`ATTRIBUTE_UID`) REFERENCES `TATTRIBUTE` (`UIDPK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='values associated with customer profiles.'

CREATE TABLE `TCUSTOMER` (
  `UIDPK` bigint(20) NOT NULL,
  `PREF_BILL_ADDRESS_UID` bigint(20) DEFAULT NULL,
  `PREF_SHIP_ADDRESS_UID` bigint(20) DEFAULT NULL,
  `CREATION_DATE` datetime NOT NULL,
  `LAST_EDIT_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `GUID` varchar(64) NOT NULL,
  `STATUS` int(11) NOT NULL,
  `AUTHENTICATION_UID` bigint(20) DEFAULT NULL,
  `STORECODE` varchar(64) DEFAULT NULL,
  `IS_FIRST_TIME_BUYER` tinyint(4) DEFAULT '1',
  `CUSTOMER_TYPE` varchar(64) NOT NULL,
  `SHARED_ID` varchar(255) NOT NULL,
  `PARENT_CUSTOMER_GUID` varchar(64) DEFAULT NULL,
  `DTYPE` varchar(40) DEFAULT 'ExtCustomerImpl',
  `LAST_SESSION_DATE` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`UIDPK`),
  UNIQUE KEY `TCUSTOMER_UNIQUE` (`GUID`),
  UNIQUE KEY `TCUSTOMER_SHARED_ID_TYPE_UNIQ` (`SHARED_ID`,`CUSTOMER_TYPE`),
  UNIQUE KEY `I_CUST_AUTH_UID` (`AUTHENTICATION_UID`),
  UNIQUE KEY `SHARED_ID` (`SHARED_ID`,`STORECODE`),
  KEY `I_CUST_CR_DATE` (`CREATION_DATE`),
  KEY `I_CUST_STORE_CODE` (`STORECODE`),
  KEY `I_TYPE_LAST_EDIT` (`CUSTOMER_TYPE`,`LAST_EDIT_DATE`),
  KEY `I_CUSTOMER_SHAREDID` (`SHARED_ID`),
  KEY `I_CUSTOMER_PARENT` (`PARENT_CUSTOMER_GUID`),
  CONSTRAINT `CUSTOMER_STORECODE_FK` FOREIGN KEY (`STORECODE`) REFERENCES `TSTORE` (`STORECODE`),
  CONSTRAINT `TCUSTOMER_PARENT_GUID_FK` FOREIGN KEY (`PARENT_CUSTOMER_GUID`) REFERENCES `TCUSTOMER` (`GUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='customer account information.'

索引

【问题讨论】:

  • 在没有任何特定代码的情况下(即使有代码),这看起来更适合 Database Administrators 甚至可能是 Server Fault
  • 发布 A) EXPLAIN SELECT ....... TEXT 结果返回相同的少量记录并需要表扫描的 ..... 查询确实存在性能问题。发布 B) 显示创建表 tbl_name;对于使用的每个查询和 POST C) 每个 SHOW INDEX FROM tbl_name;请。
  • @WilsonHauck,感谢您的回复。澄清一下,我要解决的问题是阅读器性能下降。查询的性能在编写器上不会随着时间的推移而下降,那么为什么阅读器的性能会下降。此外,考虑到连接的数量和返回的数据量,我们正在为分析运行的复杂查询预计会进行表扫描。所以我认为索引调优不会解决整体问题。
  • 如需帮助,请仅在 dba.stackoverflow.com 上发布来自您的阅读器实例的数据,大约一小时前请求。我们知道,回答看似愚蠢的请求需要时间。
  • 写入次数是否随时间增加?什么性能指标随着时间的推移而下降?它只是一个复杂的选择吗?它接触的行数是否比以前多?让我们看看查询。我会附和威尔逊的话说,这些信息可能指向一个意想不到的方向。

标签: mysql database performance database-administration amazon-aurora


【解决方案1】:

您是否尝试过从 SLOW QUERY 中删除 LOWER(xxxx)?

如果这解决了问题,并且您的结果相同,那么您只是在浪费时间进行 LOWER(xxx) 操作。

【讨论】:

  • 我正在使用 LOWER 函数来防止索引被用于匹配电子邮件。我这样做是为了查看当必须读取许多表页来解决查询时的性能。重启后慢查询的性能不是问题,它的性能会随着时间的推移而下降。
  • 监控 SHOW GLOBAL STATUS LIKE '%dirty%';每小时一次,以了解可能会随着时间的推移而导致速度变慢的脏页。在您的摘要中,记录 DIRTY PAGES 计数的日期和时间。考虑完全消除 LOWER(function) 以节省 CPU 周期和表扫描。
  • @redfish819 您是否有任何每小时监控的脏页数可以与我们分享?
【解决方案2】:

好吧,除非优化器在不同的查询计划之间随机切换,否则我无法解释性能的变化。

我确实看到您正在使用臭名昭著的实体-属性-值模式设计。并且以一种相当庞大和复杂的方式进行 - 不同数据类型的多个列。

随着数据集的增长,我确实看到了一些总体上可能有助于提高性能的东西。 (我认为它会增长。)

属性表TCUSTOMERPROFILEVALUE的主键UIDPK可能没有用。这可能会更好:PRIMARY KEY(CUSTOMER_UID, ATTRIBUTE_UID)。或者应该是LOCALIZED_ATTRIBUTE_KEY???为什么属性有两列?

更改 PK 时,此 KEY I_CPV_ATTKEY_SHORTTEXT (LOCALIZED_ATTRIBUTE_KEY,SHORT_TEXT_VALUE) 将在末尾隐式添加 CUSTOMER_UID,从而使您的 JOIN 受益。

BIGINT 通常是矫枉过正;考虑使用更小的数据类型。

你有另一个属性表-TATTRIBUTE吗?

一个表有 5 个 UNIQUE 键会减慢插入速度。也许你可以少一些?

INDEX(SHARED_ID) 是多余的,因为还有其他以该列开头的键。

【讨论】:

  • 感谢您对如何改进数据库设计提出建议。这里的大部分内容来自我们正在定制的系统,尽管某些索引可能已更改/添加。在这一点上,我们的重点是解决性能下降的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
  • 2019-02-22
  • 2014-04-15
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 2010-10-07
相关资源
最近更新 更多