MySQL加入了子查询优化

时间:2014-10-21 08:54:26

标签: mysql sql indexing

我在MySQL中有以下查询

 select * from 
    (
        select asiento, fecha, sum(debe) as debe, sum(haber) as haber
        from apuntes 
        where apuntes.sobreescrito is null
        group by asiento, fecha
        order by fecha, asiento
    )asientos 
    left join
    (
        select id_diario, asiento, fecha, sum(debe) as debe, sum(haber)  as haber
        from apuntes 
        where apuntes.sobreescrito is not null
        group by asiento, fecha, id_diario
        order by fecha, asiento
    )asientos_antiguos 
    on asientos.asiento = asientos_antiguos.asiento and asientos.fecha  = asientos_antiguos.fecha
    where 
        asientos_antiguos.debe <> asientos.debe 
        or 
        asientos_antiguos.haber <> asientos.haber 

第一个子查询(asientos)返回大约20k记录,而第二个查询,在正常情况下,应该不再返回20k记录,产生3-4秒的可接受查询,但理论上它可能重复每个操作的记录,所以我测试产生了100k记录,大约需要30秒(不可接受)。

此时,我尝试为字段“asiento”和“fecha”创建索引,但是子查询不会从中受益。另外,我为每个子查询创建了两个视图,希望我可以在这些子视图中创建一个索引,但是,视图限制包括“无索引”。

任何帮助都将不胜感激。

编辑1

好的,我会尝试解释我想要达到的目标,并随时纠正我的英语,我会使用我可能不知道的经济词汇。

我开发了一个web应用程序,可以读取包含书籍条目的excel文件(每个文件通常包含20k条记录)并将这些书籍条目保存到表格中(在我的例子中为apuntes)。

有时,如果字段“fecha”和“asiento”相同且字段“id_diario”不同,则可能会覆盖其中一些条目(注意:每个excel book都会生成一组书条目拥有“id_diario”,所以我可以区分旧记录)

此时,一切正常,但现在我必须生成一份报告,指出在某些时候,覆盖的书籍条目(财务词,不知道是否正确)是否具有与新的不同的金额那些淹没他们的人。

这是当我来到这个查询时,第一个子查询获取所有未被覆盖的记录(apuntes.sobreescrito为NULL),第二个子查询获取与第一个子查询匹配的所有覆盖记录。

在我的测试用例中,第二个子查询为每个有效的书籍条目生成3个覆盖记录(有3个覆盖操作),这意味着比较60k和20k记录。

下一步,我将使用“GROUP_CONCAT”操作生成带有第二个查询结果的json格式化数组,但是,我必须解决性能问题。

1 个答案:

答案 0 :(得分:1)

想知道你是否可以使用更基本的查询来确定存在不匹配的记录,然后只是获取那些的真实细节。如果您感兴趣的已更改记录的数量只是所有记录的一小部分,这可能会有所帮助。

例如,这样的事情应该找到已经改变的记录 -

SELECT asiento, fecha 
FROM 
( 
    SELECT id_diario, asiento, fecha, SUM(debe) AS debe, SUM(haber) AS haber 
    FROM apuntes 
    GROUP BY id_diario, asiento, fecha 
) sub0 
GROUP BY asiento, fecha 
HAVING MIN(debe) != MAX(debe) 
OR MIN(haber) != MAX(haber)

您可以使用它来缩小您需要检查的实际记录。