当前位置: 首页 > 知识库问答 >
问题:

优化数百万行的“不在(…)”查询

百里默
2023-03-14

注意:我无法访问与此问题相关的源代码/数据库。这两个表位于不同的服务器上。

我在一家第三方公司工作,该公司的系统与我们自己的系统集成。他们有一个运行类似这样的查询;

DELETE FROM table WHERE column NOT IN(1,2,3,4,5,.....3 000 000)

它在中引用了大约300万个值,而不是在中。

我试图指出,对于删除多行并保留查询中记录的所有行来说,这似乎是一种低效的方法。问题是,由于我自己没有访问源代码/数据库的权限,我不完全确定应该建议什么解决方案。

我知道这个查询的想法是保持目标服务器与源服务器同步。因此,如果在源服务器上删除了一行,则目标服务器将在运行此(和其他)查询时反映该更改。

由于知识有限,我可以向他们提出哪些可能的建议?

首先想到的是有一个标志栏,指示它是否被删除。当同步脚本运行时,它将首先在目标服务器上对标记为已删除的所有行执行更新(或插入新行),然后执行第二次查询以删除标记为已删除的所有行。

有没有更合乎逻辑的方法来做这样的事情,记住,功能上的全面检修是不可能的。由于许多原因,对当前流程只可能进行一些小的调整。


共有3个答案

施选
2023-03-14
匿名用户

删除大量行将花费大量时间。这可能需要进行完整的表扫描。当它找到要删除的行时,它将强调撤消/重做日志。它将阻塞复制(如果使用这种方法)。等

您希望删除多少行?

最好将列表分成1000块。(无论是在(常量列表)中使用,还是在JOIN中使用,这都适用),但是,由于您不这样做,它会变得更粘。最好的方法可能是复制您想要的:

CREATE TABLE new LIKE real;
INSERT INTO new
    SELECT * FROM real WHERE id IN (...);  -- without NOT
RENAME TABLE real TO old,
             new TO real;
DROP TABLE old;

我将详细介绍大删除中的分块、分区和其他技术。

黄宏毅
2023-03-14

我知道这个查询的想法是保持目标服务器与源服务器同步。因此,如果在源服务器上删除了一行,则目标服务器将在运行此(和其他)查询时反映该更改。

我知道这是显而易见的,但为什么这两台服务器不使用复制保持同步呢?我猜这是因为除了这张表,他们没有相同的数据。

如果开箱即用复制不够灵活,可以使用更改数据捕获工具。

这个想法是,该工具监控MySQL二进制日志流中的变化,并对其做出反应。反应是用户定义的,它可以包括将相同的更改应用到另一个MySQL实例,这将使它们保持同步。

这里有一个博客展示了如何使用Maxwell,它是开源CDC工具之一,这是Zendesk发布的:https://www.percona.com/blog/2016/09/13/mysql-cdc-streaming-binary-logs-and-asynchronous-triggers/

这种方法有两个优点:

  • 无需重新同步整个表。您只会在发生增量更改时应用它们。
  • 无需每天安排重新同步或其他。由于增量更改可能很小,您几乎可以立即应用更改。
温源
2023-03-14

而不是

DELETE FROM your_table 
WHERE column NOT IN(1,2,3,4,5,.....3 000 000)

你可以做的

delete t1
from your_table t1
left join table_where_the_ids_come_from t2 on t1.column = t2.id
where t2.id is null
 类似资料:
  • 问题内容: 我有以下查询: 分析表有6000万行,而交易表有3M行。 在此查询上运行时,我得到: 我已经不知道如何优化此查询了,因为它已经非常基础了。运行此查询大约需要70秒钟。 以下是存在的索引: 根据建议,在添加任何额外索引之前简化了两个表的架构,因为这并不能改善情况。 如果以上无法进一步优化。关于汇总表的任何实施建议都将非常有用。我们正在AWS上使用LAMP堆栈。上面的查询正在RDS(m1.

  • 本文向大家介绍MySQL百万级数据量分页查询方法及其优化建议,包括了MySQL百万级数据量分页查询方法及其优化建议的使用技巧和注意事项,需要的朋友参考一下 数据库SQL优化是老生常谈的问题,在面对百万级数据量的分页查询,又有什么好的优化建议呢?下面将列举了一些常用的方法,供大家参考学习! 方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM

  • 问题内容: 我最近发现并修复了我正在处理的站点中的错误,该错误导致表中有数百万行重复的数据行,即使没有行也将非常大(仍然有数百万行)。我可以轻松找到这些重复的行,并可以运行一个删除查询来杀死它们。问题是试图一次删除这么多行会长时间锁定表,如果可能的话,我想避免这种情况。我可以看到摆脱这些行而又不占用站点(通过锁定表)的唯一方法是: 编写一个脚本,该脚本将循环执行数千个较小的删除查询。从理论上讲,这

  • 问题内容: 我有一个在InnoDB引擎上运行的MySQL表,该表具有大约2,250,000行,其表结构如下: 第一列保存一个从0到2.25M的简单增量值,而&分别保存一个点的一组以十进制度表示的纬度和经度坐标。 这是一个只读表。不会添加其他行,并且唯一需要针对它运行的查询如下: …冒号后面的值是PHP PDO占位符。本质上,此查询的目标是获取表中当前位于Google Maps窗口视口中的所有坐标点

  • 主要内容:前 言,主从复制的原理是什么?,主从复制的有几种模式?,主从延迟问题和常规解决方案,读写分离实战前 言 订单缓存方案上线之后,我们以为又开启了岁月安好的日子,但是,在一周后的某一天,DBA直接跑来了,DBA直接说:“leader让我直接找你,是这样的,上次加了缓存优化后,效果确实不错,但是我发现订单查询sql在今天的12:00至12:05之间有大量的慢sql,查询时间超过了2.5s。” 这个时候,我们立马开启了排查问题模式,首先,check了一下上次加的缓存,发现缓存正常,然后接着根据

  • 问题内容: 我需要使用JavaScript在网格中向用户呈现大量数据行(即数百万行)。 用户不应一次看到页面或仅查看有限数量的数据。 相反,应该看起来所有数据都可用。 并非一次下载所有数据,而是在用户访问时下载小块(即,通过滚动网格)。 这些行不会通过此前端进行编辑,因此可接受只读网格。 对于这种无缝分页,存在哪些用JavaScript编写的数据网格? 问题答案: 以获取有关使SlickGrid与