简单的搜索功能会使用like
like语句的前导模糊查询不能使用索引,根据最左前缀原则,因为页面搜索严禁左模糊或者全模糊,如果需要可以使用搜索引擎来解决。
select * from doc where title like '%XX'; -- 不能使用索引
select * from doc where title like 'XX%'; -- 非前导模糊查询,可以使用索引
union、in、or 都能够命中索引,建议使用 in
一个是or的优化消耗CPU比较多,同时会导致数据库引擎放弃索引进行全表扫描,所以不推荐使用。而union和in的优化CPU消耗差不多,甚至union更好一些但不多,但是一般建议使用in会SQL语句简洁一些。对于开发者而言使用in会更加舒适一些。
select * from doc where status=1
union all
select * from doc where status=2;
select * from doc where status in (1, 2);
NULL
注意判断使用is null / is not null会无法使用索引,同时会导致全表扫描,一般我们都会给字段赋予默认值,避免这些特殊的情况。同时如果复合索引只要有一列有NULL值,那么该列对复合索引就无效了。
使用allow_null赋予字段,往往要注意一些特别的操作,例如在python web框架Django的serializer操作中加额外的操作会导致一些出乎意料的错误。
特殊操作
不要在索引列上面做任何操作(计算、函数、类型转换),否则会导致索引失效而转向全表扫描。
比如你的日期字段是对应到秒位的,但你偏偏用到日期位的去匹配;字符串类型的ID匹配却带整型去匹配,导致类型转换使索引失效。
计算、函数、类型转换等等操作,都建议在ORM操作的前后去处理它。同时现在WEB框架也不适宜去处理复杂的SQL类型,取出数据做额外操作为益,或用缓存等方式处理。
(个人在实践中发现用Redis去操作的收益是比较不错的)