mysql怎么删除匹配_mysql – 更快的方式删除匹配的行?

我是一个相对的新手,当谈到数据库。我们使用MySQL,我目前正在加速一个似乎需要一段时间运行的SQL语句。我环顾了一下类似的问题,但没有找到一个。

目标是移除表A中在表B中具有匹配ID的所有行。

我目前正在做以下事情:

DELETE FROM a WHERE EXISTS (SELECT b.id FROM b WHERE b.id = a.id);

表a中约有100K行,表b中约22K行。列“id”是两个表的PK。

这个语句在我的测试盒上运行大约3分钟 – 奔腾D,XP SP3,2GB RAM,MySQL 5.0.67。这对我来说似乎很慢。也许不是,但我希望加快速度。有更好/更快的方法来完成这个吗?

编辑:

一些可能有帮助的附加信息。表A和B具有与我已经执行以下操作创建表B相同的结构:

CREATE TABLE b LIKE a;

表a(因此表b)有几个索引,以帮助加快查询。再次,我是一个相对的新手在DB工作,仍在学习。我不知道有什么效果,如果有的话,这对事情。我认为它的确有一个效果,因为索引也必须清理,对吧?我也想知道是否有任何其他的数据库设置,可能会影响速度。

此外,我使用INNO DB。

这里是一些额外的信息,可能对您有所帮助。

表A具有类似的结构(我已经清理了这一点):

DROP TABLE IF EXISTS `frobozz`.`a`;

CREATE TABLE `frobozz`.`a` (

`id` bigint(20) unsigned NOT NULL auto_increment,

`fk_g` varchar(30) NOT NULL,

`h` int(10) unsigned default NULL,

`i` longtext,

`j` bigint(20) NOT NULL,

`k` bigint(20) default NULL,

`l` varchar(45) NOT NULL,

`m` int(10) unsigned default NULL,

`n` varchar(20) default NULL,

`o` bigint(20) NOT NULL,

`p` tinyint(1) NOT NULL,

PRIMARY KEY USING BTREE (`id`),

KEY `idx_l` (`l`),

KEY `idx_h` USING BTREE (`h`),

KEY `idx_m` USING BTREE (`m`),

KEY `idx_fk_g` USING BTREE (`fk_g`),

KEY `fk_g_frobozz` (`id`,`fk_g`),

CONSTRAINT `fk_g_frobozz` FOREIGN KEY (`fk_g`) REFERENCES `frotz` (`g`)

) ENGINE=InnoDB AUTO_INCREMENT=179369 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

我怀疑部分问题是有这个表的许多索引。

表B看起来类似于表B,尽管它仅包含列id和h。

另外,分析结果如下:

starting 0.000018

checking query cache for query 0.000044

checking permissions 0.000005

Opening tables 0.000009

init 0.000019

optimizing 0.000004

executing 0.000043

end 0.000005

end 0.000002

query end 0.000003

freeing items 0.000007

logging slow query 0.000002

cleaning up 0.000002

解决了

感谢所有的回应和评论。他们肯定让我想到这个问题。通过询问一个简单的问题“做任何其他表引用a.id?”让我离开这个问题

问题是在表A上有一个DELETE TRIGGER,它调用一个存储过程来更新两个其他表C和D.表C有一个FK回a.id,并且在存储过程中做了一些与该id相关的东西之后,它有声明,

DELETE FROM c WHERE c.id = theId;

我查看了EXPLAIN语句并重写为,

EXPLAIN SELECT * FROM c WHERE c.other_id = 12345;

所以,我可以看到这是做什么,它给了我以下信息:

id 1

select_type SIMPLE

table c

type ALL

possible_keys NULL

key NULL

key_len NULL

ref NULL

rows 2633

Extra using where

这告诉我,这是一个痛苦的操作,因为它会被调用22500次(对于给定的数据集被删除),这是问题。一旦我在该other_id列上创建了INDEX并重新引用EXPLAIN,我得到:

id 1

select_type SIMPLE

table c

type ref

possible_keys Index_1

key Index_1

key_len 8

ref const

rows 1

Extra

更好,其实真的很棒。

我添加了Index_1,我的删除时间与mattkemp报告的时间一致。这是一个非常微妙的错误,我的部分,由于在最后一分钟的鞋履一些额外的功能。原来,建议的替代的DELETE / SELECT语句大多数,如丹尼尔所说,最终基本上采取了相同的时间量和soulmerge提到,语句是几乎是最好的,我将能够构建基于什么我需要做。一旦我为这个其他表C提供了索引,我的DELETE就很快。

死后:

从这个练习中得到了两个教训。首先,很明显,我没有利用EXPLAIN语句的力量来更好地了解我的SQL查询的影响。这是一个新秀的错误,所以我不会打败自己的那一个。我会从这个错误中学习。第二,冒犯的代码是“快速完成”的心态的结果,不适当的设计/测试导致这个问题没有更快出现。如果我生成了几个相当大的测试数据集用作这个新功能的测试输入,我不会浪费我的时间也不是你的。我在数据库端的测试缺乏我的应用程序端到位的深度。现在我有机会改进。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL的内连接和左连接的效率问题不是绝对的,它们的效率取决于具体的查询语句和表结构。在某些情况下,内连接可能更快,而在其他情况下,左连接可能更快。一般情况下,内连接的效率比左连接更快,因为内连接只返回两个表之间匹配,而左连接需要返回左表的所有匹配的右表的,如果右表中没有匹配,则返回NULL值。但是在某些情况下,使用左连接可以避免查询中的重复数据,提高查询效率。因此,选择使用内连接还是左连接应该根据具体的需求和查询条件来决定。 ### 回答2: MySQL的内连接和左连接的效率并没有绝对的答案,因为它们的效率取决于具体的数据库设计、索引使用和查询需求等多个因素。 内连接是通过匹配两张表之间的共同数据来返回结果。它仅返回匹配,如果表之间没有匹配的数据,那么将不会返回任何结果。由于内连接只返回匹配,所以它通常是比较高效的。如果在连接的列上存在索引,那么内连接的效率将更高,因为索引能够加速数据的查找和匹配过程。 左连接是将左表中的所有数据都返回,同时匹配表中的数据。如果右表中没有匹配的数据,那么结果中对应的字段就会显示为NULL。左连接会返回较多的数据,所以在一些情况下可能会比较耗时。但是如果查询需要获取左表的全部数据,无论是否存在匹配的右表数据,那么左连接是更合适的选择。 总的来说,内连接在某些具体的场景下可能比左连接更高效,因为它只返回匹配的数据。但是在其他情况下,左连接可能更适合获取完整的数据集。不同的查询需求和数据库设计都会对效率产生影响,因此在实际应用中,我们需要根据具体情况选择合适的连接方式。 ### 回答3: MySQL的内连接和左连接的效率取决于具体的查询和数据情况。一般情况下,内连接的效率更高。 内连接是通过比较两个表之间的关联字段,并返回满足条件的记录。它只返回两个表中关联字段匹配的数据,因此它们通常需要比较少的数据量,从而提高查询效率。 左连接是根据左表的记录,联接右表的记录,并返回所有左表的记录以及满足关联条件的右表记录。这意味着左连接可能返回大量的数据,尤其是右表中含有大量匹配记录时。因此左连接在某些情况下可能会降低查询效率。 然而,具体的情况可能因查询条件、数据量和表结构等因素而异。如果左表和右表的数据量相似,内连接和左连接的效率可能没有明显差异。而如果右表中匹配记录非常少,左连接可能会在一定程度上更快,因为它不需要进大量的数据匹配。 总的来说,内连接和左连接的效率取决于实际情况,通常情况下内连接更快,但在特定情况下左连接也可能具有更高的效率。对于具体的查询,可以通过分析执计划和性能测试来确定最佳的连接方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值