【问题标题】:MySQL performance differences between a different "FROM" operator usage不同“FROM”运算符用法之间的 MySQL 性能差异
【发布时间】:2013-09-07 05:34:43
【问题描述】:

谁能给我解释一下为什么会这样:

SELECT 
    A.id,
    A.name,
    B.id AS title_id
FROM title_information AS A
JOIN titles B ON B.title_id = A.id
WHERE
    A.name LIKE '%testing%'

比这慢得多(6-7 倍):

SELECT 
    A.id,
    A.name,
    B.id AS title_id
FROM (SELECT id, name FROM title_information) AS A
JOIN titles B ON B.title_id = A.id
WHERE
    A.name LIKE '%testing%'

我知道如果不了解有关架构和 MySQL 配置的完整详细信息,可能很难回答这个问题,但我正在寻找任何一般原因,为什么第一个示例可能比第二个示例慢得多?

运行 EXPLAIN 给出了这个:

|| *id* || *select_type* || *table*  || *type*  || *possible_keys*           || *key*   || *key_len* || *ref*             || *rows* || *Extra*     ||
|| 1    || SIMPLE        || B        || index   ||                           || id      || 12        ||                   || 80407  || Using index ||
|| 1    || SIMPLE        || A        || eq_ref  || PRIMARY,id_UNIQUE,Index 4 || PRIMARY || 4         || newsql.B.title_id || 1      || Using where ||

|| *id* || *select_type* || *table*           || *type* || *possible_keys* || *key*   || *key_len* || *ref* || *rows* || *Extra*                         ||
|| 1    || PRIMARY       || B                 || index  ||                 || id      || 12        ||       || 80407  || Using index                     ||
|| 1    || PRIMARY       || <derived2>        || ALL    ||                 ||         ||           ||       || 71038  || Using where; Using join buffer  ||
|| 2    || DERIVED       || title_information || index  ||                 || Index 4 || 206       ||       || 71038  || Using index                     ||

更新: A.id 和 B.id 都是 PRIMARY KEYS,而 A.name 是索引。两个表都有大约 50,000 行 (~15MB)。 MySQL 配置几乎是默认配置。

不确定这是否有帮助(或者它是否会增加混乱 - 就像它对我一样),但使用可能有更多匹配字段的更通用的 LIKE 语句(例如 "LIKE '%x%' ") 使第一个查询运行得更快。另一方面,使用 "LIKE '%there are no records matching this%'" 将使第二个查询更快(而第一个查询很困难)。

任何人都可以了解这里发生了什么?

谢谢!

【问题讨论】:

  • 您选择的行数是否相同?例如,我希望第一个查询可能比前​​ 20 行查询更快,但是如果您得到所有​​内容,优化器 应该 以类似方式对待它们。你的索引是什么?
  • @Ben 所有选定的字段都被索引。实际上 A.id 和 B.id 都是 UNIQUE PRIMARY KEY,而 A.name 是一个简单的索引。是的,我还假设第一个与第二个相同或更快。但这不是我所看到的,这带来了所有这些混乱。在我的表中,执行时间相应地是 ~3s vs ~0.5s。
  • 表使用什么引擎? MySQL的版本是多少?

标签: mysql sql database performance database-schema


【解决方案1】:

这是推测(我阅读 MySQL 解释输出的能力比应有的弱,因为我想看数据流图)。

但这就是我认为正在发生的事情。第一个查询是说“让我们通过 B 并在 A 中查找适当的值”。然后它使用id 索引查找适当的值,然后它需要获取页面并与name 进行比较。这些访问效率低下,因为它们不是顺序的。

第二个版本似乎认为name 的条件很重要。它正在遍历 A 上的 name 索引,并且仅根据需要获取匹配的行。这更快,因为数据在索引中,并且匹配名称只需要很少的页面。与 B 的匹配非常简单,只有一行要匹配。

我对性能差异感到惊讶。通常,派生表的性能较差,但这显然是一个例外。

【讨论】:

    猜你喜欢
    • 2011-02-27
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2011-04-24
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多