Py学习  »  DATABASE

MySQL计划和子查询与依赖子查询性能

bpeikes • 2 年前 • 738 次点击  

我们正处于从MySql 5.7迁移到8的中期。我们有两个开发系统,大多数情况下都运行良好。我们发现问题的一个地方是,我们在生产服务器上有一个查询<2秒,但在我们的两个转换系统上,不会超过50秒。

我们在不同的计划中注意到的一点是,在我们的生产系统中 select_type 具体步骤如下:

身份证件 选择_类型
1. 主要的,重要的
2. 依赖子查询
3. 子查询
3. 子查询
3. 子查询
3. 子查询

在我们的转换数据库(8.0)中,该计划看起来像

身份证件 选择_类型
1. 主要的,重要的
2. 依赖子查询
2. 依赖子查询
2. 依赖子查询
2. 依赖子查询
2. 依赖子查询

这个 table , type , key ref 列是相同的。唯一的区别似乎在于 Extra 专栏,但我不确定是什么导致了这些差异。

知道其中一些行是依赖子查询还是依赖子查询有什么影响吗?

查询的基础是:

SELECT e.ent_id, e.status_id, COUNT(e.id) AS cnt
FROM Events e
WHERE
e.ent_id IN (1)
AND
NOT EXISTS 
(
    SELECT eam.acct
    FROM EventAccountMapping eam
    WHERE 
      eam.event_id = e.id AND
      eam.account NOT IN
      (
          SELECT uam.account
          FROM UserAccountMapping uam
          WHERE uam.user_id = 109
      )
)

请注意,此部分不依赖于查询的任何其他部分:

SELECT uam.account
FROM UserAccountMapping uam
WHERE uam.user_id = 109

然而,优化器似乎将其视为一个依赖查询。此外,如果用查询结果替换该子查询,查询将在1秒内运行。即

eam.account NOT IN
(
     'abc',
     'def',
     'ghi'
)

出于某种原因,优化器认为 UserAccountMappings 取决于查询的其余部分。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128958
 
738 次点击  
文章 [ 2 ]  |  最新文章 2 年前
SelvaRaj B
Reply   •   1 楼
SelvaRaj B    2 年前

您可以通过启用或禁用其中一个优化器来共享两个版本的优化器列表的输出吗?这可能是产生不同查询计划的原因之一。

选择@optimizer\u开关;

这就像在黑暗中拍摄,信息在这里共享。

a) 在5.7中,您仍然尝试强制索引来强制优化器选择性能更好的索引。 b) 您是否匹配了5.7和8.0环境中数据集的基数 c) 您可以尝试操纵索引统计信息,迫使优化器选择不同的索引,而不是默认索引。 d) 做 explain format=json 这将为您提供更多有关查询成本的原因,以及查询执行时到底发生了什么。

Rick James
Reply   •   2 楼
Rick James    2 年前

哎哟双重否定。让我的大脑受伤。

这些索引可能有助于:

e:  INDEX(ent_id,  status_id)
uam:  INDEX(user_id,  account)
eam:  INDEX(event_id, account,  acct)

添加复合索引后,删除具有相同前导列的索引。 也就是说,当你有索引(a)和索引(a,b)时,扔掉前者。

请给我们看看 整个 EXPLAIN SELECT ...