繁体   English   中英

利用IN性能改善删除

[英]Improve delete with IN performance

我很难在MariaDB 5.5.44数据库中编写DELETE查询。

以下两个代码示例中的第一个效果很好,但是我需要在其中添加WHERE语句。 这将显示在第二个代码示例中。

我只需要从polozkyTransakci中删除transakce_tmp表中的puvodFaktury <> FAKTURA VO CZ 我以为第二个示例中的WHERE语句可以与内部SELECT一起使用,但是它需要花很长时间才能处理(在基于云的ETL工具中大约需要40分钟),即使这样,它也不会留下我想要的行。

1。

DELETE FROM polozkyTransakci
WHERE typPolozky = 'odpocetZalohy';

2。

DELETE FROM polozkyTransakci
WHERE typPolozky = 'odpocetZalohy'
     AND idTransakce NOT IN (
 SELECT idTransakce
 FROM transakce_tmp
 WHERE puvodFaktury = 'FAKTURA VO CZ');

向任何人致谢一百万

大卫

IN对性能非常不利。尝试使用NOT EXISTS()

DELETE FROM polozkyTransakci 
WHERE typPolozky = 'odpocetZalohy'
     AND NOT EXISTS (SELECT 1
                     FROM transakce_tmp r
                     WHERE r.puvodFaktury = 'FAKTURA VO CZ'
                          AND r.idTransakce = polozkyTransakci.idTransakce );

在进行性能调整之前,您需要弄清楚为什么它没有删除正确的行。

因此,首先要进行选择,直到找到正确的行。 请在每次检查结果时建立一些选择,以查看是否获得所需的结果。

选择之后,即可转换为删除。 测试删除时,它是一个事务,并对遗留的数据进行一些测试,以确保在回滚或提交之前正确删除了该数据。 由于您可能想对性能进行调整,因此建议您回退,以便随后可以再次尝试对性能进行调整的版本,以确保获得相同的结果。 当然,您只想在开发服务器上执行此操作!

现在,尽管我同意不存在可能会更快,但是您要查看的其他一些内容是:

  • 您是否正在发生级联删除? 如果最终删除许多子记录,则可能是问题的一部分。
  • 是否有影响删除的触发器? 尤其要看是否有人设置了一行一行地而不是一组地运行。 当您删除许多记录时,逐行触发器是一件非常糟糕的事情。 例如,假设您要删除5万条记录,并且对审计表有删除触发器。 如果一次向该表插入一条记录,则该记录将被执行50K次。 如果它一步插入所有已删除的记录,则单独插入可能会花费更长的时间,但总执行时间要短得多。
  • 您有什么索引,它对删除有帮助吗?
  • 您将要检查每个查询的解释计划,以查看它们是否在改进查询执行方式的详细信息。

性能调优是一件复杂的事情,最好阅读特定数据库可用的一些性能调优书来详细阅读它。

我可能倾向于将查询写为LEFT JOIN ,尽管我猜测这将具有与NOT EXISTS相同的性能计划:

DELETE pt
    FROM polozkyTransakci pt LEFT JOIN
         transakce_tmp tt
         ON pt.idTransakce = tt.idTransakce AND
            tt.puvodFaktury = 'FAKTURA VO CZ'
    WHERE pt.typPolozky = 'odpocetZalohy' AND tt.idTransakce IS NULL;

如果没有索引,我会推荐索引: polozkyTransakci(typPolozky, idTransakce)transakce_tmp(idTransakce, puvodFaktury) 这些也可以在NOT EXISTS版本上使用。

您可以使用SELECT测试这些查询的性能:

    SELECT pt.*
    FROM polozkyTransakci pt LEFT JOIN
         transakce_tmp tt
         ON pt.idTransakce = tt.idTransakce AND
            tt.puvodFaktury = 'FAKTURA VO CZ'
    WHERE pt.typPolozky = 'odpocetZalohy' AND tt.idTransakce IS NULL;

DELETE应该更慢(由于记录事务的成本),但是性能应该是可比的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM