MySql查询花费的时间太长
我有一张桌子MySql查询花费的时间太长,mysql,database,performance,database-performance,database-optimization,Mysql,Database,Performance,Database Performance,Database Optimization,我有一张桌子 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(1
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);
我正在尝试使用以下查询搜索此表:
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;
该表包含180362行。如果我去掉where子句,运行只需要0.157秒,但是使用where子句运行需要很长时间(超过300秒),在这一点上我只是取消它
为什么添加where子句需要这么长时间才能运行?
你对我如何加快速度有什么建议吗
编辑:
当我使用原始索引运行explain语句时,我得到:
当我使用@Simulant建议的语句运行explain语句时(将o1添加到索引中),我得到:
但是执行这个查询也需要很长的时间 如果您想要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
已在另一个索引中编入索引。但是一个查询一次只能对一个表使用一个索引。您应该做的是将查询所需的所有列添加到同一索引中
CREATE INDEX input_data_index
ON temp (i1, i2, i3, i4, i5, i6, i7, i8, i9, o1);
使用该语句可以帮助您了解索引减少扫描行的效果。
INDEX((i1, i2, i3, i4, i5, i6, i7, i8, i9, o1)
并将WHERE子句更改为
WHERE t.o1 > x.o1;
这将把输出的行数减少一半,并可能改变查询的执行方式。它可能在连接上为每一行单独运行where查询,即它正在执行数千个查询。这种问题是设计糟糕得令人震惊的症状尝试删除
o1
上的索引。这可能会使优化器感到困惑。您是否有任何关于如何修复设计的建议?只要您枚举了列(比如2以上),就可以确定您的设计有缺陷。我不知道I和o是什么,所以我不能进一步评论,但请看规范化。谢谢,但它不会产生预期的结果。我也不知道是谁否决了你的帖子,哈哈,如果你把鼠标悬停在向下箭头上,它可能会提供线索。@User9813。如果唯一的原因是它产生了单例,那么您可以包括having min(o1)max(o1)
@User9813-它以什么方式不产生期望的结果?你是说它没有40列,而i
列是重复的吗?或者您需要所有20个o
列?还是别的什么?@RickJames我的意思是,我只想创建原始表(没有重复的列),我现在意识到,由于我在原始select语句中使用了“*”,所以您无法看到它。另外,我只想看到包含i1,i2。。。i9对于两个表是相同的,但o1对于两个表是不同的。基于这一推理,将WHERE
更改为HAVING
会有所帮助。