MySQL强制使用索引的两种方式及优化索引

MySQL强制使用索引的两种方式及优化索引

创建测试数据

创建表和索引

sql 复制代码
-- 创建表
CREATE TABLE `tbl_test` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(100) NOT NULL COMMENT '姓名',
  `item_code` bigint NOT NULL COMMENT '子项编号',
  `order_code` varchar(100) NOT NULL COMMENT '订单编号',
  `id_card` varchar(30) NOT NULL COMMENT '身份证',
  `goods_number` bigint NOT NULL COMMENT '商品数量',
  `amount` decimal(6,2) NOT NULL COMMENT '金额',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `random` bigint NOT NULL COMMENT '数据数',
  PRIMARY KEY (`id`),
  KEY `index_item_code` (`item_code`),
  KEY `index_id_card` (`id_card`),
  KEY `index_random` (`random`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;


-- 在tbl_test表中,goods_number列上创建索引
CREATE INDEX index_goods_number ON tbl_test (goods_number);
-- 在tbl_test表中,删除名称为 index_goods_number 的索引
ALTER TABLE tbl_test DROP INDEX index_goods_number;

创建插数存储过程

sql 复制代码
-- 创建存储过程
delimiter //
create procedure insert_data() begin declare i INT default 1;
while i <= 100000 DO
insert into tbl_test (
    name,
	item_code,
	order_code,
	id_card,
	goods_number,
	amount,
	create_time,
	random)
values (
   CONCAT("test", i),
   i,
   CONCAT("order", i),
   FLOOR(RAND() * 10000000000000),
   i,
   ROUND(RAND() * 100, 2),
   NOW(),
   FLOOR(RAND() * 1000000)
 );
set
i = i + 1;
end while;
end
//
delimiter ;

-- 调用储存过程
CALL insert_data();

MySQL强制使用索引的两种方式

使用 FORCE INDEX 语句

sql 复制代码
explain
    select
        *
    from
       tbl_test force index (index_item_code)
    where
       (item_code between 1 and 1000) and (random between 50000 and 1000000)
    order by
        random
    limit 1\G




*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: tbl_test
   partitions: NULL
         type: range
possible_keys: index_item_code
          key: index_item_code
      key_len: 8
          ref: NULL
         rows: 1000
     filtered: 11.11
        Extra: Using index condition; Using where; Using filesort
1 row in set, 1 warning (0.00 sec)

使用 USE INDEX 语句

sql 复制代码
explain
     select
        *
     from
        tbl_test USE index (index_item_code)
     where
        (item_code between 1 and 1000) and (random between 50000 and 1000000)
     order by
        random
     limit 1\G


*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: tbl_test
   partitions: NULL
         type: range
possible_keys: index_item_code
          key: index_item_code
      key_len: 8
          ref: NULL
         rows: 1000
     filtered: 11.11
        Extra: Using index condition; Using where; Using filesort
1 row in set, 1 warning (0.00 sec)

FORCE INDEX 或 USE INDEX 的区别?

  • FORCE INDEX :这个语句指示MySQL强制查询使用特定的索引。它会忽略优化器的选择,无论索引的选择性如何,都会使用指定的索引。这意味着即使使用了不太适合的索引,MySQL也会强制使用它。这可能会导致性能下降,因为不适合的索引可能会导致查询变慢。
  • USE INDEX :这个语句也允许你指定要使用的索引,但它与"FORCE INDEX"不同的是,它只是暗示MySQL在可能的情况下使用指定的索引。如果MySQL认为其他索引更适合查询,它仍然可以选择其他索引。这样可以保留一定的灵活性,让MySQL根据实际情况选择最佳的索引。
  • 总的来说,"FORCE INDEX"是强制使用指定索引,而"USE INDEX"是暗示使用指定索引,但MySQL仍然可以根据优化器的判断选择其他索引。实际使用时,应根据具体情况进行评估选择。
相关推荐
骇客野人5 小时前
mysql笛卡尔积怎么形成的怎么避免笛卡尔积
数据库·mysql
m0_564264185 小时前
IDEA DEBUG调试时如何获取 MyBatis-Plus 动态拼接的 SQL?
java·数据库·spring boot·sql·mybatis·debug·mybatis-plus
隐语SecretFlow7 小时前
隐语SecreFlow SCQL 1.0.0b1 发布:更完善的 SQL 支持与更高效的隐私查询引擎
数据库·sql
ttghgfhhjxkl7 小时前
文档搜索引擎搜索模块的索引更新策略:实时增量与全量重建设计
数据库·搜索引擎
老华带你飞7 小时前
机器人信息|基于Springboot的机器人门户展示系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·机器人·论文·毕设·机器人门户展示系统
StarRocks_labs7 小时前
StarRocks 在 Cisco Webex 的探索与实践
数据库·starrocks·json·存算分离·olap 技术栈
notion20257 小时前
Adobe Lightroom Classic下载与安装教程(附安装包) 2025最新版详细图文安装教程
java·数据库·其他·adobe
unicrom_深圳市由你创科技7 小时前
用 CTE 重构嵌套子查询:让复杂报表 SQL 可读性提升 80%
mysql·重构
楚枫默寒8 小时前
mongodb备份脚本(单机+副本集)
数据库
小蒜学长8 小时前
springboot酒店客房管理系统设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端