我正在使用 MySQL 5.7。我创建了一个带有 DATETIME 类型的虚拟列(未存储)的表,上面有一个索引。当我在处理它时,我注意到 order by 并没有返回所有数据(我期望在顶部的一些数据丢失了)。MAX 和 MIN 的结果也是错误的。我跑之后
ANALYZE TABLE
CHECK TABLE
OPTIMIZE TABLE
那么结果是正确的。我猜索引数据有问题,所以我有几个问题:
- 何时以及为什么会发生这种情况?
- 有没有办法防止这种情况?
- 在我运行的 3 个命令中,哪个是正确的?
我担心将来会发生这种情况,但我不会注意到。
编辑:
按照评论中的要求,我添加了表定义:
CREATE TABLE `items` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned DEFAULT NULL,
`image` json DEFAULT NULL,
`status` json DEFAULT NULL,
`status_expired` tinyint(1) GENERATED ALWAYS AS (ifnull(json_contains(`status`,'true','$.expired'),false)) VIRTUAL COMMENT 'used for index: it checks if status contains expired=true',
`lifetime` tinyint(4) NOT NULL,
`expiration` datetime GENERATED ALWAYS AS ((`create_date` + interval `lifetime` day)) VIRTUAL,
`last_update` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `expiration` (`status_expired`,`expiration`) USING BTREE,
CONSTRAINT `ts_competition_item_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `ts_user_core` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1312459 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED
返回错误结果的查询:
SELECT * FROM items ORDER BY expiration DESC;
SELECT max(expiration),min(expiration) FROM items;
谢谢