文章部分引用自 链接
数据库引擎会放弃索引进行全表扫描,如果不是必要,尽量别这么干
select id from user where name like '%codeMan%' //×
如果你要的只是用户名,为啥你要用*呢,不要返回用不到的任何字段,万一用户的属性有几十行,你只是想要个用户名,何必呢。又耗性能、又不能使用到覆盖索引
select * from user // ×
select user_name from user // √
考虑在where和order by涉及的列加索引
数据库引擎会放弃索引进行全表扫描,如果不是必要,尽量别这么干
换句话说,你可以用0来代替null,索引 NULL 列需要额外的空间来保存,所以要占用更多的空间
进行比较和计算时要对 NULL 值做特别的处理
数据库引擎会放弃索引进行全表扫描
数据库引擎会放弃索引进行全表扫描
select id from user where money / 10 = 10
你不能这样写么?
select id from user where money = 10 * 10
都给我弄到 “ = ” 右边去
select id form user where substring(user_name,1,4)='code' //×
给我这样写
select id from user where user_name like 'code%'
数据库引擎会放弃索引进行全表扫描,如果是连续数值,你可以用between;如果是子查询,你可以用exists,很多时候用exists代替in是一个好选择
数据库引擎会放弃索引进行全表扫描
select id from user where money = 50 or money = 100 //×
给我这样写
select id from user where money = 50 union all select id from user where money = 100
通常子查询在 in 子句中,且子查询中为简单 SQL(不包含 union、group by、order by、limit 从句) 时,才可以把子查询转化为关联查询进行优化。
子查询性能差的原因:
子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大。
由于子查询会产生大量的临时表也没有索引,所以会消耗过多的 CPU 和 IO 资源,产生大量的慢查询。
这样才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致
所以,我们要把区分度高、长度小、使用最频繁的放在联合索引的最左侧
SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,比如表中有个字段sex,只有男和女,有必要去建索引吗?没有,这样反而适得其反。
数据变更需要维护索引,因此更多的索引意味着更多的维护成本。
更多的索引意味着更多的存储空间。
索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率, 因为 insert 或 update 时有可能会重建索引,因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。
据说有个潜规则:单张表索引不超过 5 个
覆盖索引:就是包含了所有查询字段 (where,select,ordery by,group by 包含的字段) 的索引
varchar是变长字段,可以节省存储空间,搜索效率高
尽量不要使用游标,效率较差
通常我们存在服务器,或者调用像七牛云的API存储大二进制文件,数据库保存获取文件的链接即可
既减少了sql编译的所需时间,又解决了sql注入的问题
ps:
关于索引的深入,可以深入浅出看看这两篇文章,都是转载自极客的一位老师写的,觉得写的很好~
索引1
索引2