HollowDjj Asked: 2024-05-04 16:09:20 +0800 CST2024-05-04 16:09:20 +0800 CST 2024-05-04 16:09:20 +0800 CST MySQL:按随机 ID 选择时索引无效 772 有一张桌子: `id` INT(10) NOT NULL AUTO_INCREMENT, `status` TINYINT(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) USING BTREE, 当我处理流动语句(该表中有超过 1000 条记录)时,会处理表扫描。为什么主键索引不起作用? SELECT * FROM t_test WHERE id = FLOOR(1 + RAND() * 1000) 有时会出现两种不同的结果,为什么会发生这种情况? 当mysql通过随机id选择时索引无效并且有时返回两个不同的值 mysql 1 个回答 Voted Best Answer Luuk 2024-05-04T16:34:08+08:002024-05-04T16:34:08+08:00 执行此操作时: WITH abc AS (SELECT FLOOR(1 + RAND() * 1000) as R) SELECT * FROM t_test WHERE id = (SELECT R FROM abc); 您可能期望 CTE 仅返回一条记录,并且可以使用索引。 但是当添加 EXPLAIN 时它显示UNCACHEABLE: ID 选择类型 桌子 分区 类型 可能的键 钥匙 密钥长度 参考 行 过滤的 额外的 1 基本的 t_测试 无效的 全部 无效的 无效的 无效的 无效的 1024 100.00 使用地点 2 无法缓存 子查询 无效的 系统 无效的 无效的 无效的 无效的 1 100.00 3 衍生的 无效的 无效的 无效的 无效的 无效的 无效的 无效的 无效的 无效的 没有使用表 编辑: 刚刚在文档中找到了这个: 困难源于这样一个事实:RAND() 函数对表的每一行都计算一次。为了避免多重功能评估,请使用以下技术之一 将包含非确定性函数的表达式移至单独的语句,并将值保存在变量中。在原始语句中,将表达式替换为对变量的引用,优化器可以将其视为常量值: SET @keyval = FLOOR(1 + RAND() * 49); UPDATE t SET col_a = some_expr WHERE id = @keyval;
执行此操作时:
您可能期望 CTE 仅返回一条记录,并且可以使用索引。
但是当添加 EXPLAIN 时它显示UNCACHEABLE:
编辑:
刚刚在文档中找到了这个:
困难源于这样一个事实:RAND() 函数对表的每一行都计算一次。为了避免多重功能评估,请使用以下技术之一