Ita*_*vka 28 mysql sql comparison performance
检查问题此SELECT查询需要180秒才能完成(检查问题本身的注释).
IN只能与一个值进行比较,但时差仍然很大.
为什么会那样?
Mar*_*ers 47
简介:这是MySQL中的一个已知问题,并在MySQL 5.6.x中得到修复.问题是由于使用IN的子查询被错误地识别为从属子查询而不是独立子查询时缺少优化.
当您在原始查询上运行EXPLAIN时,它返回:
1 'PRIMARY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 2 'DEPENDENT SUBQUERY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 3 'DEPENDENT SUBQUERY' 'question_law' 'ALL' '' '' '' '' 10040 'Using where'
当你改变IN
为=
你得到这个:
1 'PRIMARY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 2 'SUBQUERY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 3 'SUBQUERY' 'question_law' 'ALL' '' '' '' '' 10040 'Using where'
每个从属子查询在其包含的查询中每行运行一次,而子查询仅运行一次.当有条件可以转换为连接时,MySQL有时可以优化从属子查询,但事实并非如此.
现在这当然留下了为什么MySQL认为IN版本需要是依赖子查询的问题.我已经制作了查询的简化版本以帮助调查此问题.我创建了两个表'foo'和'bar',其中前者只包含一个id列,后者包含id和foo id(虽然我没有创建外键约束).然后我用1000行填充了两个表:
CREATE TABLE foo (id INT PRIMARY KEY NOT NULL);
CREATE TABLE bar (id INT PRIMARY KEY, foo_id INT NOT NULL);
-- populate tables with 1000 rows in each
SELECT id
FROM foo
WHERE id IN
(
SELECT MAX(foo_id)
FROM bar
);
Run Code Online (Sandbox Code Playgroud)
此简化查询具有与以前相同的问题 - 内部选择被视为从属子查询,并且不执行优化,导致内部查询每行运行一次.查询需要几秒钟才能运行.再次更改IN
为=
允许查询几乎立即运行.
我用来填充表格的代码如下,以防有人希望重现结果.
CREATE TABLE filler (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=Memory;
DELIMITER $$
CREATE PROCEDURE prc_filler(cnt INT)
BEGIN
DECLARE _cnt INT;
SET _cnt = 1;
WHILE _cnt <= cnt DO
INSERT
INTO filler
SELECT _cnt;
SET _cnt = _cnt + 1;
END WHILE;
END
$$
DELIMITER ;
CALL prc_filler(1000);
INSERT foo SELECT id FROM filler;
INSERT bar SELECT id, id FROM filler;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5808 次 |
最近记录: |