假设我们有一个带有 MySQL 5.6 数据库的 Web 论坛应用程序,许多用户可以 24/7 全天候访问该应用程序。现在有一个这样的表,用于发送给用户的通知的元数据。
| notifications | CREATE TABLE `notifications` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`message_store_id` bigint(20) unsigned NOT NULL,
`status` varchar(10) COLLATE ascii_bin NOT NULL,
`sent_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`,`sent_date`)
) ENGINE=InnoDB AUTO_INCREMENT=736601 DEFAULT CHARSET=ascii COLLATE=ascii_bin |
Run Code Online (Sandbox Code Playgroud)
该表有 100 万行。有了这个表,某个 message_store_id 由于某种原因突然变得无效,我计划使用单个删除语句删除所有具有该 message_store_id 的记录,例如
DELETE FROM notifications WHERE message_store_id = 12345;
Run Code Online (Sandbox Code Playgroud)
由于这条消息被发送给了如此多的用户,因此这一条语句影响了表的 10%。同时,成千上万的用户一直在访问此通知表,因此必须存在索引。显然,删除记录时重新创建索引的成本非常高,所以我担心这样做会导致服务器资源最大化而导致停机。但是,如果我删除索引,删除记录然后再次添加索引,我必须关闭数据库一段时间,不幸的是我们的服务无法使用。
我希望 MySQL 5.6 不会愚蠢到这个单一的语句可以杀死数据库,但我想它很有可能。我的问题是,对于这种情况,索引重建真的是致命的吗?如果是这样,此操作是否有任何不需要我停止数据库进行维护的好策略?