MySQL加入子查询优化

标签 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 秒( Not Acceptable )。

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

如有任何帮助,我们将不胜感激。

编辑 1

好的,我会尝试解释我想要实现的目标,并随意纠正我的英语,我将使用我可能不知道的金融术语。

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

有时,如果字段“fecha”和“asiento”相同而字段“id_diario”不同,则其中一些条目可能会被覆盖(注意:每本 Excel 书籍都会生成一组书籍条目及其拥有“id_diario”,这样我就可以区分较旧的记录)

此时,一切正常,但现在我必须生成一份报告,表明在某些时候,被覆盖的书籍条目(财务词,不知道它是否正确)的金额是否与新的金额不同那些覆盖它们的。

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

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

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

最佳答案

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

例如,类似这样的内容应该找到已更改的记录 -

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)

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

关于MySQL加入子查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26482638/

相关文章:

java - 如何修复 "tables are already present using metadata"camunda进程引擎异常?

php - 获取php和mysqli中插入数据的Id

sql - 是否建议在 Oracle EBS 并发程序中提交一个 Commit?

javascript - 在Js中使用循环查找具有特定值的数据的索引

mysql - 为什么直接列值比较在 mysql 中的多个 like 子句后不评估

mysql - 从 Ruby Hash 构建 SQL 语句

sql - 是否可以在 Golang 的帮助下创建具有动态名称的 PostgreSQL 数据库?

python - 使用代码在numpy数组中查找两个值之间的差

sql - 在空表上创建索引后插入数据还是在oracle上插入数据后创建唯一索引?

c# - 使用 C# 添加 entityFramework 部分