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仍然可以根据优化器的判断选择其他索引。实际使用时,应根据具体情况进行评估选择。