0

[编辑]

目标是使用自连接基于顺序字段(sequentialsortfield)以特定顺序减去字段(somevalue)的值。查询原样给出正确的结果,但是对于大型数据集非常慢。使用 mysql 'explain' 表明该查询不使用索引,而是使用文件排序,尽管所有三个示例字段都已编入索引。如果我删除“order by”,它不再使用 filesort [但] 不会根据所需的顺序产生正确的结果。

我在 SO 或 MySQL 文档上搜索并没有看到任何有用的信息。除非我放弃它,否则似乎无法避免using filesort在 table1 上,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;
4

2 回答 2

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;
于 2013-10-23T19:35:29.253 回答
0

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

我建议创建两个复合索引并尝试隐式强制其中一个:

说,

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 优化器会根据查询选择适当的索引)。

于 2013-10-24T11:13:39.587 回答