2013-10-23 34 views
0

[编辑]优化的MySQL自联接查询与不同的位置和顺序

目标是使用自联接基于序列字段(sequentialsortfield)以一定的顺序中减去一个字段(someValue中)的值。查询按原样提供了正确的结果,但大数据集非常缓慢。使用mysql'explain'显示这个查询不是使用索引,而是使用filesort,尽管所有三个示例字段都被编入索引。如果我删除'order by',它不再使用filesort [但是]不会根据所需的顺序产生正确的结果。

我已经搜索和没有看到SO或MySQL文档已经帮助。在table1上似乎无法避免using filesort,除非我放弃order by但我确实需要它。指数存在于所有三个领域。

已经通过示例来说明我的问题。

结构 “表”:

id     INT 
somevalue    INT 
sequentialsortfield INT 

查询:

select table1.somevalue-table2.somevalue as PrevRowDiff 
FROM table AS table1, 
table AS table2 
WHERE table1.sequentialsortfield+1 = table2.sequentialsortfield 
order by id; 
+1

我不确定你想要做什么..你能更好地解释自己吗? – jcho360

+0

使用自连接以某种顺序减去字段的值。查询结果正确,但大数据集非常缓慢。使用mysql'explain'显示这个查询不是使用索引,而是使用filesort。如果我删除'order by',它会进行优化,但不会根据所需的顺序产生正确的结果。 – TransitDataHead

+0

有没有附加条件?或者你要转储整个大型数据集? – newtover

回答

0

它实际上是相当棘手的,使这个查询效率。长话短说,当你在sequentialsortfield(无论如何需要联接有效)都有覆盖索引时,你需要强制MySQL以主键顺序输出数据。

我会建议建立两个综合指数,并试图暗中迫使他们中的一个:

说,

ALTER TABLE the_table ADD KEY the_one_to_force (id, sequentialsortfield, somevalue); 
ALTER TABLE the_table ADD KEY usual_one (sequentialsortfield, somevalue); 

和重写查询如下(你并不需要一个ORDER BY在这种情况下, ):

SELECT t1.somevalue-t2.somevalue as PrevRowDiff 
FROM the_table t1 FORCE INDEX (the_one_to_force) 
JOIN the_table t2 ON t1.sequentialsortfield+1 = t2.sequentialsortfield 

的想法是,该数据将在the_one_to_force指数和输出数据的顺序,如果有匹配被读取(因为它实际发生无论如何,但是合适的索引是由MySQL优化器根据查询选择的)。

+0

听起来合乎逻辑我会尽快给你一个镜头并更新 - 谢谢! – TransitDataHead

+0

工作就像一个魅力!谢谢谢谢。 – TransitDataHead

0

试试这个:

Select table1.somevalue-table2.somevalue as PrevRowDiff 
FROM table AS table1 
Join table AS table2 
on table1.sequentialsortfield+1 = table2.sequentialsortfield 
group by sequentialsortfield 
order by id; 
+0

谢谢你的尝试。这导致了“使用临时;使用filesort”与原来的“使用filesort”。 – TransitDataHead