2

我有一個表的MySQL查詢時間太長

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子句時需要很長時間才能運行? 你對我如何加快速度有什麼建議嗎?

編輯:

當我運行使用原始索引我有我得到的解釋聲明:img

當我使用@Simulant的一個建議運行EXPLAIN語句(添加01到索引)我得到:img2

但這個查詢仍然需要很長時間才能執行。

+0

它可能會在連接上單獨運行每行的where查詢,即它正在執行數千個查詢。 – MadHatter

+1

這種問題是令人震驚的糟糕設計的症狀 – Strawberry

+0

嘗試刪除'o1'上的索引。這可能會讓優化器感到困惑。 –

回答

0

如果你想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; 

這是不完全一樣的結果集,但它可能會滿足您的需求。

+0

爲什麼會以匿名方式降級? –

+0

謝謝,但沒有它不會產生所需的結果。另外我不知道誰投了你的帖子,大聲笑 – User9813

+1

如果你把鼠標懸停在向下的箭頭上,它可能會提供一個線索。 – Strawberry

0

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); 

使用explain語句可以幫助您找出索引如何減少掃描的行。

+0

根據這條推理,把'WHERE'改成'HAVING'會有所幫助。 –

0

INDEX((i1, i2, i3, i4, i5, i6, i7, i8, i9, o1) 

而WHERE子句更改爲

WHERE t.o1 > x.o1; 

這將減少在輸出的行數的一半,並可能改變執行查詢的方式。