リストの1つに属するユーザーを含むテーブルがありますが、テーブルには現在約2,300万行があります。
テーブルの構造:
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
テーブルには現在、いくつかの3つの インデックスがあり
ます
。
条件を満たす行の数に、削除にかかる時間の奇妙な依存関係があります。
2K rows - 0.0847 sec, 5K – 0.2856 , 10K – 21.3428 , 20K – 34.41, 50K – 61.2596,
100K - 99.7257.
オンラインでリストをクリアしませんが、この操作をキューに入れ、バックグラウンドで1000人のサブスクライバーによって削除します。
しかし、なぜ時間が5Kから10K行に大幅に増加するのだろうか。なぜそれが起こるのか誰かが説明できますか?