MySql 查询时间过长
MySql querying taking too long
我有一个table
CREATE TABLE temp (
i1 DECIMAL(10, 5),
i2 DECIMAL(10, 5),
i3 DECIMAL(10, 5),
i4 DECIMAL(10, 5),
i5 DECIMAL(10, 5),
i6 DECIMAL(10, 5),
i7 DECIMAL(10, 5),
i8 DECIMAL(10, 5),
i9 DECIMAL(10, 5),
o1 DECIMAL(10, 5),
o2 DECIMAL(10, 5),
o3 DECIMAL(10, 5),
o4 DECIMAL(10, 5),
o5 DECIMAL(10, 5),
o6 DECIMAL(10, 5),
o7 DECIMAL(10, 5),
o8 DECIMAL(10, 5),
o9 DECIMAL(10, 5)
);
CREATE INDEX input_data_index
ON temp (i1, i2, i3, i4, i5, i6, i7, i8, i9);
CREATE INDEX test_index
ON temp (o1);
我正在尝试使用以下查询来搜索此 table:
SELECT * FROM temp t
INNER JOIN temp x
ON t.i1 = x.i1
AND t.i2 = x.i2
AND t.i3 = x.i3
AND t.i4 = x.i4
AND t.i5 = x.i5
AND t.i6 = x.i6
AND t.i7 = x.i7
AND t.i8 = x.i8
AND t.i9 = x.i9
WHERE t.o1 != x.o1;
table 包含 180,362 行。如果我去掉 where 子句,到 运行 只需要 0.157 秒,但是对于 where 子句,到 运行 需要很长时间(超过 300 秒),此时我只是取消它。
为什么添加 where 子句后 运行 需要这么长时间?
您对我如何加快速度有什么建议吗?
编辑:
当我 运行 使用原始索引的解释语句时,我得到:img
当我 运行 使用@Simulant 建议的解释语句(将 o1 添加到索引)时,我得到:img2
但是执行此查询仍然需要很长时间。
如果你想要 o1 的值,其中 i 值相同,你可以考虑:
select i1, i2, i3, i4, i5, i6, i7, i8, i9,
group_concat(o1)
from temp
group by i1, i2, i3, i4, i5, i6, i7, i8, i9;
这不是完全相同的结果集,但它可能会满足您的需要。
列 i1, i2, i3, i4, i5, i6, i7, i8, i9
在同一个索引中编入索引,因此没有 where
的查询会被索引充分利用。您的列 o1
已在另一个索引中编入索引。但是一个查询一次只能使用一个索引一个table。您应该做的是将查询所需的所有列添加到同一索引。
CREATE INDEX input_data_index
ON temp (i1, i2, i3, i4, i5, i6, i7, i8, i9, o1);
使用 explain
语句可以帮助您了解索引减少扫描行数的效果。
有
INDEX((i1, i2, i3, i4, i5, i6, i7, i8, i9, o1)
并将 WHERE 子句更改为
WHERE t.o1 > x.o1;
这会将输出的行数减少一半,并且可能改变查询的执行方式。
我有一个table
CREATE TABLE temp (
i1 DECIMAL(10, 5),
i2 DECIMAL(10, 5),
i3 DECIMAL(10, 5),
i4 DECIMAL(10, 5),
i5 DECIMAL(10, 5),
i6 DECIMAL(10, 5),
i7 DECIMAL(10, 5),
i8 DECIMAL(10, 5),
i9 DECIMAL(10, 5),
o1 DECIMAL(10, 5),
o2 DECIMAL(10, 5),
o3 DECIMAL(10, 5),
o4 DECIMAL(10, 5),
o5 DECIMAL(10, 5),
o6 DECIMAL(10, 5),
o7 DECIMAL(10, 5),
o8 DECIMAL(10, 5),
o9 DECIMAL(10, 5)
);
CREATE INDEX input_data_index
ON temp (i1, i2, i3, i4, i5, i6, i7, i8, i9);
CREATE INDEX test_index
ON temp (o1);
我正在尝试使用以下查询来搜索此 table:
SELECT * FROM temp t
INNER JOIN temp x
ON t.i1 = x.i1
AND t.i2 = x.i2
AND t.i3 = x.i3
AND t.i4 = x.i4
AND t.i5 = x.i5
AND t.i6 = x.i6
AND t.i7 = x.i7
AND t.i8 = x.i8
AND t.i9 = x.i9
WHERE t.o1 != x.o1;
table 包含 180,362 行。如果我去掉 where 子句,到 运行 只需要 0.157 秒,但是对于 where 子句,到 运行 需要很长时间(超过 300 秒),此时我只是取消它。
为什么添加 where 子句后 运行 需要这么长时间? 您对我如何加快速度有什么建议吗?
编辑:
当我 运行 使用原始索引的解释语句时,我得到:img
当我 运行 使用@Simulant 建议的解释语句(将 o1 添加到索引)时,我得到:img2
但是执行此查询仍然需要很长时间。
如果你想要 o1 的值,其中 i 值相同,你可以考虑:
select i1, i2, i3, i4, i5, i6, i7, i8, i9,
group_concat(o1)
from temp
group by i1, i2, i3, i4, i5, i6, i7, i8, i9;
这不是完全相同的结果集,但它可能会满足您的需要。
列 i1, i2, i3, i4, i5, i6, i7, i8, i9
在同一个索引中编入索引,因此没有 where
的查询会被索引充分利用。您的列 o1
已在另一个索引中编入索引。但是一个查询一次只能使用一个索引一个table。您应该做的是将查询所需的所有列添加到同一索引。
CREATE INDEX input_data_index
ON temp (i1, i2, i3, i4, i5, i6, i7, i8, i9, o1);
使用 explain
语句可以帮助您了解索引减少扫描行数的效果。
有
INDEX((i1, i2, i3, i4, i5, i6, i7, i8, i9, o1)
并将 WHERE 子句更改为
WHERE t.o1 > x.o1;
这会将输出的行数减少一半,并且可能改变查询的执行方式。