1

我有一个表,其中包含属于其中一个列表的用户,该表现在大约有 23M 行。

表结构:

    CREATE TABLE `contacts` (
 `subscriber_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `list_id` int(10) unsigned NOT NULL,
 `account_id` int(10) unsigned NOT NULL,
 `subscriber_key` char(32) COLLATE utf8_unicode_ci NOT NULL,
 `email_address` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `first_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 `last_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
 `ip` int(10) unsigned DEFAULT NULL COMMENT '\nThe ip address of the subscriber that we can get when he opens the \nthe email or subscribe using subsribe form.\nTheoretically it can be used to segment by Location (which is not correct if someone uses proxy).',
 `preferred_format` tinyint(4) NOT NULL DEFAULT '0' COMMENT 'Preferred format of \n0 - HTML, \n1 -Text,\n2 - Mobile',
 `state` tinyint(4) NOT NULL DEFAULT '4' COMMENT '1 - subscribed2 - unsubscribed3 - cleaned4 - not confirmed, it means the user subscribed but has not confirmed it yet.',
 `unsubscribe_reason` tinyint(4) NOT NULL DEFAULT '0',
 `unsubscribe_reason_description` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `cause_of_cleaning` tinyint(4) NOT NULL DEFAULT '0' COMMENT '\nThis field is the cause of moving the subscriber to the \n0 - not used\n1 - spam complaint\n2 - hard bounce\n3 - several soft bounces',
 `date_added` datetime NOT NULL COMMENT 'The data when the subscriber was added. I suppose this field can be used in the conditions forming the segment',
 `last_changed` datetime NOT NULL,
 `unsubscribe_date` datetime DEFAULT NULL,
 PRIMARY KEY (`subscriber_id`),
 UNIQUE KEY `email_list_id` (`email_address`,`list_id`),
 KEY `FK_list_id` (`list_id`),
 CONSTRAINT `FK_list_id` FOREIGN KEY (`list_id`) REFERENCES `lists` (`list_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=42236572 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='\nEmails and other contact info about\nthe people'

有时子表中可能有数据到具有附加字段的联系人,但在这种情况下(对于 list_id = 81)没有这样的数据。

请求

EXPLAIN SELECT *
FROM contancts
WHERE list_id =81

表明:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  subscribers     ref     FK_list_id  FK_list_id  4   const   1 

当我尝试删除满足条件的行时:

DELETE
FROM contancts
WHERE list_id=81

Tha 表现在有大约 3 个索引: 订阅者 0 PRIMARY 1 订阅者 ID A 23196385 NULL NULL BTREE
订阅者 0 email_list_id 1 email_address A 23196385 NULL NULL BTREE
订阅者 0 email_list_id 2 list_id A 23196385 NULL NULL BTREE
订阅者 1 FK_list_id 1 list_id A 17 NULL NULL BTREE

我看到删除满足条件的行数所花费的时间的奇怪依赖性:

2K rows - 0.0847 sec, 5K – 0.2856 , 10K – 21.3428 , 20K – 34.41, 50K – 61.2596, 
100K - 99.7257.

我现在不清除在线列表,但将此操作排队,并在后台将其删除 1000 个订阅者。

但我想知道为什么时间从 5K 增加到 10K 行这么多。有人可以解释为什么会这样吗?

4

0 回答 0