有人可以向我解释原因:
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'%没有匹配此%'的记录”将使第二个查询更快(而第一个查询挣扎)。
任何人都可以了解这里发生的事情?
谢谢!
答案 0 :(得分:0)
这是猜测(我阅读MySQL解释输出的能力比应该的要弱,因为我想查看数据流图)。
但这是我认为正在发生的事情。第一个问题是“让我们通过B并在A中查找适当的值”。然后,它使用id
索引查找适当的值,然后需要获取页面并与name
进行比较。这些访问效率低下,因为它们不是顺序的。
第二个版本似乎认识到name
上的条件很重要。它通过A上的name
索引,只根据需要获取匹配的行。这样更快,因为数据在索引中,匹配名称需要几页。与B的匹配非常简单,只有一行匹配。
我对性能差异感到惊讶。通常,派生表在性能方面表现不佳,但这显然是个例外。