尝试一下这个SQL

select * from film WHERE film_id + 1 = 100

  • MySQL中,对索引字段做函数操作,优化器会放弃索引

    时间函数

    select * from rental where month(rental_date) = 5
    查看这张表的索引
    image.png
    explain一下
    image.png

  • 使用month()函数后,无法使用索引

  • 需要去掉month()函数,换成between

select * from rental where rental_date between ‘2005-5-1’ and ‘2005-6-1’ OR rental_date BETWEEN ‘2006-5-1’ AND ‘2006-6-1

字符串与数字比较

  • MySQL中若出现字符串与数字比较,会将字符串转换为数字

select * from t1 where f1 = 6;

  • 如果t1表中f1字段为varchar类型,则此SQL相当于:

select * from t1 where CAST(f1 AS signed int) = 6;

  • 处理方法:将第一个SQL中的6改为’6’
  • 如果字段为int类型,6和’6’分别会是什么情况?

    隐式字符编码转换

    ``sql CREATE TABLEt1(f1varchar(32) NOT NULL,f2int NOT NULL, KEYidx_f1(f1), KEYidx_f2(f2`) ) ENGINE= InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE t2 ( f1 varchar(32) NOT NULL, f2 int NOT NULL, KEY idx_f1 (f1), KEY idx_f2 (f2) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO sakila.t1(f1, f2) VALUES (‘4’, 6); INSERT INTO sakila.t1(f1, f2) VALUES (‘6’, 3); INSERT INTO sakila.t1(f1, f2) VALUES (‘7’, 1);

INSERT INTO sakila.t2(f1, f2) VALUES (‘4’, 5); INSERT INTO sakila.t2(f1, f2) VALUES (‘2’, 4); INSERT INTO sakila.t2(f1, f2) VALUES (‘2’, 4); ```

总结

  • MySQL中,对索引字段做函数操作,优化器会放弃索引
  • 这种情况可能包括:时间函数,字符串转数字,字符编码转换
  • 解决方案:时间函数转区间、数字强转字符串、高级编码转低级