如何从庞大的MySQL表中删除符合条件的行?

如何从庞大的MySQL表中删除符合条件的行?,mysql,sql-delete,database-indexes,Mysql,Sql Delete,Database Indexes,我正在我的一个应用程序中使用MySQL数据库,其中一个表的大小约为10GB。我想从此表中删除符合条件的行。删除查询的格式为: Delete from table_name where (a,b,c) in ((1,2,3),(1,5,6)); 字段(a、b、c)上有一个综合索引。查询删除行需要几分钟的时间,而我希望操作在毫秒或几秒钟内完成。我怎样才能做到这一点?字段上的单个索引是否比多列索引快 我的意思是,如果查询是: Delete from table_name where a = 1 an

我正在我的一个应用程序中使用MySQL数据库,其中一个表的大小约为10GB。我想从此表中删除符合条件的行。删除查询的格式为:

Delete from table_name
where (a,b,c) in ((1,2,3),(1,5,6));
字段(a、b、c)上有一个综合索引。查询删除行需要几分钟的时间,而我希望操作在毫秒或几秒钟内完成。我怎样才能做到这一点?字段上的单个索引是否比多列索引快

我的意思是,如果查询是:

Delete from table_name
where a = 1 and (b,c) in ((2,3),(5,6));

这会产生更快的结果吗?

如果(a,b,c)有一组不同的值,那么可以根据这些值对表进行分区。在对表进行分区之后,“deleting”反而会删除分区,而且速度非常快

MySQL 5.7提供了对列表列分区的支持。这是列表分区的一个变体,允许使用多个列作为分区键,并允许使用除整数类型以外的数据类型的列作为分区列

文档中的示例表:

CREATE TABLE customers_1 (
   first_name VARCHAR(25),
   last_name VARCHAR(25),
   street_1 VARCHAR(30),
   street_2 VARCHAR(30),
   city VARCHAR(15),
   renewal DATE
)
PARTITION BY LIST COLUMNS(city) (
   PARTITION pRegion_1 VALUES IN('Oskarshamn', 'Högsby', 'Mönsterås'),
   PARTITION pRegion_2 VALUES IN('Vimmerby', 'Hultsfred', 'Västervik'),
   PARTITION pRegion_3 VALUES IN('Nässjö', 'Eksjö', 'Vetlanda'),
   PARTITION pRegion_4 VALUES IN('Uppvidinge', 'Alvesta', 'Växjo')
);
我在文档中找不到使用多列作为分区键的示例,但正如您所料,它看起来像

CREATE TABLE customers_2 (
    first_name VARCHAR(25),
    last_name VARCHAR(25),
    street_1 VARCHAR(30),
    street_2 VARCHAR(30),
    city VARCHAR(15),
    renewal DATE
)
PARTITION BY LIST COLUMNS(first_name,last_name) (
    PARTITION me_partition VALUES IN(('Alden','W'),('Aldino','W')),
    PARTITION you_partition VALUES IN(('Pooja','Gupta'),('PJ','Gupta'))
);
要对表进行分区,可以使用一些高级的动态sql

SET SESSION group_concat_max_len = 1000000000;
SET @i = 0;
SELECT CONCAT('ALTER TABLE customers_2
PARTITION BY LIST COLUMNS(first_name,last_name) (
    ',GROUP_CONCAT('PARTITION partition_',@i:=@i+1,' VALUES 
IN((''',d.first_name,''',''',d.last_name,'''))' SEPARATOR 
',\n\t'),'
);')
FROM (
    SELECT DISTINCT first_name, last_name
    FROM customers_2
) d;
这将生成以下alter语句

ALTER TABLE customers_2
PARTITION BY LIST COLUMNS(first_name,last_name) (
    PARTITION partition_1 VALUES IN(('Alden','W')),
    PARTITION partition_2 VALUES IN(('Jon','Smith')),
    PARTITION partition_3 VALUES IN(('Other','Name')),
    ...
);
如何在“in”子句中获取元组?可能重复的