本地/实时站点上的相同查询,性能大不相同

Posted

技术标签:

【中文标题】本地/实时站点上的相同查询,性能大不相同【英文标题】:Same query on local/live site, vastly different performance 【发布时间】:2021-07-02 16:20:44 【问题描述】:

我的慢查询日志显示一个看似正常的查询随机运行了 5,6+ 秒。在我的站点的本地克隆上运行相同的查询会产生 0.05 秒的查询运行时间。这是两者的解释:

谈到 mysql 优化时,我有点紧张,但是,我不明白这怎么会产生如此不同的结果?表格大致相同,实时站点更新更多,但其他方面非常相似。


编辑:

我没有与我的本地安装进行比较,而是与我的“旧”实时服务器进行比较。我今天早上刚搬了服务器。

表的OLD server DDL:

CREATE TABLE `wp_bp_activity` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `user_id` bigint(20) NOT NULL,
 `component` varchar(75) COLLATE utf8mb4_unicode_ci NOT NULL,
 `type` varchar(75) COLLATE utf8mb4_unicode_ci NOT NULL,
 `action` text COLLATE utf8mb4_unicode_ci NOT NULL,
 `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
 `primary_link` text COLLATE utf8mb4_unicode_ci NOT NULL,
 `item_id` bigint(20) NOT NULL,
 `secondary_item_id` bigint(20) DEFAULT NULL,
 `date_recorded` datetime NOT NULL,
 `hide_sitewide` tinyint(1) DEFAULT 0,
 `mptt_left` int(11) NOT NULL DEFAULT 0,
 `mptt_right` int(11) NOT NULL DEFAULT 0,
 `is_spam` tinyint(1) NOT NULL DEFAULT 0,
 PRIMARY KEY (`id`),
 KEY `date_recorded` (`date_recorded`),
 KEY `user_id` (`user_id`),
 KEY `item_id` (`item_id`),
 KEY `secondary_item_id` (`secondary_item_id`),
 KEY `component` (`component`),
 KEY `type` (`type`),
 KEY `mptt_left` (`mptt_left`),
 KEY `mptt_right` (`mptt_right`),
 KEY `hide_sitewide` (`hide_sitewide`),
 KEY `is_spam` (`is_spam`),
 FULLTEXT KEY `content` (`content`)
) ENGINE=InnoDB AUTO_INCREMENT=1060622 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

新的服务器 DDL:

CREATE TABLE `wp_bp_activity` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `user_id` bigint(20) NOT NULL,
 `component` varchar(75) COLLATE utf8mb4_unicode_ci NOT NULL,
 `type` varchar(75) COLLATE utf8mb4_unicode_ci NOT NULL,
 `action` text COLLATE utf8mb4_unicode_ci NOT NULL,
 `content` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
 `primary_link` text COLLATE utf8mb4_unicode_ci NOT NULL,
 `item_id` bigint(20) NOT NULL,
 `secondary_item_id` bigint(20) DEFAULT NULL,
 `date_recorded` datetime NOT NULL,
 `hide_sitewide` tinyint(1) DEFAULT 0,
 `mptt_left` int(11) NOT NULL DEFAULT 0,
 `mptt_right` int(11) NOT NULL DEFAULT 0,
 `is_spam` tinyint(1) NOT NULL DEFAULT 0,
 PRIMARY KEY (`id`),
 KEY `date_recorded` (`date_recorded`),
 KEY `user_id` (`user_id`),
 KEY `item_id` (`item_id`),
 KEY `secondary_item_id` (`secondary_item_id`),
 KEY `component` (`component`),
 KEY `type` (`type`),
 KEY `mptt_left` (`mptt_left`),
 KEY `mptt_right` (`mptt_right`),
 KEY `hide_sitewide` (`hide_sitewide`),
 KEY `is_spam` (`is_spam`),
 FULLTEXT KEY `content` (`content`)
) ENGINE=InnoDB AUTO_INCREMENT=1060840 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

它们是相同的,但您可以在每个底部看到行数(通过 AUTO_INCREMENT)。它们非常相似。正如我所说,这个旧服务器今天早上处于活动状态,所以这里也有很多最近的日期时间。

然而,在两台服务器上运行上图所示的查询会导致“EXPLAIN”输出的相同差异,新服务器以 10 倍的时间检查大量行。

【问题讨论】:

我正在查看您的屏幕截图,有两件事突然出现在我身上:1) 一个查询返回 32 行 vs 200K 行 2) 一个查询使用 where vs intersect - 如果没有更多详细信息,很难知道性能差异是,但我会首先开始查看(2),因为这显然指向正在使用的两个不同查询(这可能解释了差异) @blurfus 这也是我注意到的,但正如您在上面的 sql 文本中看到的那样,它是完全相同的查询吗? 我的错,它们看起来一样,但可能还有其他因素(索引、读/写量、交易量)——仅看屏幕截图很难分辨 我最好的猜测是每个环境中的行数都大不相同。特别是,Live 有更多的日期。这很重要,因为 Order By,尤其是在基础表未按日期索引的情况下。因此,请编辑问题以提供两件事;用于创建表的 DDL(在两种环境中,以防它们不同)和数据配置文件中差异的描述(有多少行,跨越多少个日期,有多少 is_spam 或不同类型等) )。 我得走了,我也建议在这里问:dba.stackexchange.com 【参考方案1】:

使用“复合”索引(按此顺序):

INDEX(is_spam, hide_sitewide, type)

提示:当EXPLAIN 说“相交”时,您需要一个复合索引。

摆脱a.type NOT IN ...,因为该测试已经由a.type IN ...处理

去掉DISTINCT,它可能会导致额外的去重。

使用EXPLAIN FORMAT=JSON SELECT ... 获取更多详细信息。

在这个论坛中使用文字,不是图片

两台服务器之间的版本可能存在差异——这可以解释使用(或误用)不同的优化技术。

【讨论】:

不幸的是,这就是我想要避免的。查询来自 WP 插件,除非我手动编辑文件,否则我无法控制它。如果我没有年复一年以及这些相同查询的大量服务器转换......我会很好地执行。唯一的区别是旧服务器上的 MariaDB 10.5.8 和新服务器上的 10.5.9。 添加索引独立于 WP 及其插件。 WP 及其插件无法像我建议的索引那样进行简单的优化。 好的...所以,我添加了该复合索引并且它起作用了。但以一种奇怪的方式。首先,我必须按照您指定的顺序添加列,这很有趣。但现在更有趣的是,EXPLAIN 告诉我“可能的键”,这个新创建的复合索引就是其中之一......但它不使用它作为实际键,现在它使用“date_recorded”之类的应该从一开始就有。如果我删除复合索引,它将停止使用 date_recorded 并返回到 index_merge。有点奇怪,但它解决了这个问题。我可能需要为查询范围添加一些复合索引 @FTLRalph - 是的,这很有趣。如果 EXPLAIN FORMAT=JSON... 没有帮助,“优化器跟踪”可能会。

以上是关于本地/实时站点上的相同查询,性能大不相同的主要内容,如果未能解决你的问题,请参考以下文章

如何在实时服务器中设置多个站点?

cfc中的查询返回本地的[n]项,但在实时站点上重复第一个元素[n]次

本地存储如何在域级别上工作?两个站点使用相同的密钥来存储数据? [复制]

用户登录 LocalHost 时出现意外的 HTTP 500 错误,但在实时站点上登录成功 [关闭]

IIS 工作进程对同一服务器上的相同站点的内存使用率很高

Wordpress:将本地主机数据库导入实时站点时出现问题