1 使用or可能会使索引失效,从而全表扫描。
解决方案:union all或 union
当偏移量最大的时候,查询效率就会越低。
解决方案:
/方案一 :返回上次查询的最大记录(偏移量)
select id,name from employee where id>10000 limit 10.
//方案二:order by + 索引
select id,name from employee order by id limit 10000,10
2 如果用到模糊关键字查询,很容易想到like,但是like很可能让你的索引失效。
解决方案:把% 放关键字后面,还是会走索引的:select userId,name from user where userId like '123%';
索引列上使用mysql的内置函数,索引失效
3 避免在 where 子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫
Inner join 、left join、right join,优先使用Inner join,如果是left join,左边表结果尽量小
,如果有条件的尽量放到左边处理。
反例:select * from tab1 t1 left join tab2 t2 on t1.size = t2.size where t1.id>2;
正例:select * from (select * from tab1 where id >2) t1 left join tab2 t2 on t1.size = t2.size;
4 避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
在 where 及 order by 涉及的列上建立索引,尽量避免全表扫描。
如果插入数据过多,考虑批量插入。
反例:
for(User u :list){
INSERT into user(name,age) values(#name#,#age#)
}
正例:
//一次500批量插入,分批进行
insert into user(name,age) values
<foreach collection="list" item="item" index="index" separator=",">
(#{item.name},#{item.age})
</foreach>
删除冗余和重复索引:重复的索引需要维护,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能的
避免同时修改或删除过多数据。解决方案:分批处理
使用默认值代替null,如果把null值,换成默认值,很多时候让走索引成为可能
尽可能使用varchar/nvarchar 代替 char/nchar。因为首先变长字段存储空间小,可以节省存储空间。
字段类型是字符串,where时一定用引号括起来,否则索引失效。因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较。
============
由于唯一索引会把null看做值,所以无法将多个缺少唯一索引中的健的文档插入到集合中。
可以通过创建稀疏索引的方式来进行,一个值可存在可不存在,如果存在就必须是唯一的。我们只需要添加一个spare选项就能创建稀疏索引。
$or 查询是两次独立查询拼接而成,效率没有使用 $IN的高
$ne 或者 $nin 操作在索引上是无效的