代码之家  ›  专栏  ›  技术社区  ›  HollowDjj

MySQL:随机id选择时索引无效

  •  0
  • HollowDjj  · 技术社区  · 3 周前

    有一张桌子:

    `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)
    

    enter image description here 有时会有两种不同的结果,为什么会发生这种情况? enter image description here

    当mysql通过随机id进行选择时,索引无效,有时会返回两个不同的值

    1 回复  |  直到 3 周前
        1
  •  0
  •   Luuk failingproudly    3 周前

    执行此操作时:

    WITH abc AS (SELECT FLOOR(1 + RAND() * 1000) as  R)
    SELECT * FROM t_test WHERE id = (SELECT R FROM abc);
    

    您可能期望CTE只返回一条记录,并且可以使用索引。

    但当添加EXPLAIN时,它显示 不可支票的 :

    身份证件 select_type 桌子 分区 类型 可能的密钥 钥匙 key_len 裁判 已过滤 额外的
    1. 初级 t_test 无效的 所有 无效的 无效的 无效的 无效的 1024 100 使用where
    2. 不可支票的 子查询 无效的 系统 无效的 无效的 无效的 无效的 1. 100
    3. 派生的 无效的 无效的 无效的 无效的 无效的 无效的 无效的 无效的 无效的 未使用表

    编辑:

    刚刚在文档中找到了这个:

    The difficulties stem from the fact that the RAND() function is evaluated once for every row of the table. To avoid multiple function evaluations, use one of these techniques

    将包含不确定性函数的表达式移到单独的语句中,将值保存在变量中。在原始语句中,将表达式替换为对变量的引用,优化器可以将其视为常数值:

    SET @keyval = FLOOR(1 + RAND() * 49);
    UPDATE t SET col_a = some_expr WHERE id = @keyval;