技术问题, mysql, 如果某表某字段离散度很小,但分布及不均匀, 如仅有‘是’、’否‘两种数值, 但‘是’的数据可能仅为 100 个以内的数量, 全部数据有 100 万或更多, 现在需要查询状态为‘是’的数据,如何优化查询。

查看 25|回复 1
作者:zf1968   
目前想到的方案:
1 、直接对此字段加索引? 但 gpt 回答,还未自己验证,如果索引离散度太低,可能 mysql 查询优化器会自动退化为全表扫描
2 、再建一个新表,专门存状态为‘是’的数据的 id 。 相当于自建了一个仅包含部分数据的索引, 但这种又会增加代码复杂度,对业务逻辑有侵入
Tiaoooo   
试一下分区后加索引呢
以下内容来自 ai:
-- 假设我们有一个名为 'user_activities' 的表
CREATE TABLE user_activities (
id INT AUTO_INCREMENT,
user_id INT,
activity_type VARCHAR(50),
status ENUM('是', '否'),
created_at TIMESTAMP,
PRIMARY KEY (id, status)
) ENGINE=InnoDB;
-- 按 status 列进行分区
ALTER TABLE user_activities
PARTITION BY LIST COLUMNS(status) (
PARTITION p_yes VALUES IN ('是'),
PARTITION p_no VALUES IN ('否')
);
-- 插入一些示例数据
INSERT INTO user_activities (user_id, activity_type, status, created_at) VALUES
(1, '登录', '是', NOW()),
(2, '购买', '否', NOW()),
(3, '评论', '是', NOW()),
(4, '浏览', '否', NOW());
-- 查询 status 为 '是' 的记录
EXPLAIN SELECT * FROM user_activities WHERE status = '是';
-- 添加索引以进一步优化查询
CREATE INDEX idx_status_created_at ON user_activities(status, created_at);
-- 再次解释查询计划
EXPLAIN SELECT * FROM user_activities WHERE status = '是' ORDER BY created_at DESC LIMIT 10;
-- 查看分区信息
SELECT PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'user_activities';
您需要登录后才可以回帖 登录 | 立即注册

返回顶部