小表不推荐使用索引,索引需要额外的开销(空间,时间,维护)
有索引但未被用到的情况
- 尽量避免Like的参数以通配符开头,否则数据库引擎会放弃使用索引而进行全表扫描
select * from t_credit_detail where Flistid like ‘%0’\G 全表扫描,没有使用到索引,不建议使用
select * from t_credit_detail where Flistid like ‘2%’\G 用到了索引,是有范围的查找了,比以通配符开头的sql语句效率提高不少
总结:用到like 尽快在后面添加通配符 - where条件不符合最左前缀原则时 最左前缀原则主要使用在联合索引中
1.abc是联合索引时,只有当a或者ab或者abc为条件时才能触发索引 如果出现ac 是因为使用了a字段 导致触发索引
2.如果是abc 都有字段的时候 顺序无所谓,可以触发索引
总结:用到联合索引的时候,尽量和联合顺序一致 - 使用!= 或 <> 操作符时
尽量避免使用!= 或 <>操作符,否则数据库引擎会放弃使用索引而进行全表扫描。
总结:使用>或<会比较高效。 - 索引列参与计算
应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。 - 对字段进行null值判断
应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
低效:select * from t_credit_detail where Flistid is null ;
可以在Flistid上设置默认值0,确保表中Flistid列没有null值,然后这样查询:
高效:select * from t_credit_detail where Flistid =0; - 使用or来连接条件
应尽量避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
低效:select * from t_credit_detail where Flistid = ‘2000000608201108010831508721’ or Flistid = ‘10000200001’;
可以用下面这样的查询代替上面的 or 查询:
高效:select from t_credit_detail where Flistid = ‘2000000608201108010831508721’ union all select from t_credit_detail where Flistid = ‘10000200001’; - 避免select *
在解析的过程中,会将’*’ 依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。
所以,应该养成一个需要什么就取什么的好习惯。 - order by 语句优化
任何在Order by语句的非索引项或者有计算表达式都将降低查询速度。
方法: 1.重写order by语句以使用索引;
2.为所使用的列建立另外一个索引
3.绝对避免在order by子句中使用表达式。 - 用 exists 代替 in
很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num) - 使用 varchar/nvarchar 代替 char/nchar
尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些 - 能用DISTINCT的就不用GROUP BY
SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID
可改为:
SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10 - 能用UNION ALL就不要用UNION
UNION ALL不执行SELECT DISTINCT函数,这样就会减少很多不必要的资源 - 在Join表的时候使用相当类型的例,并将其索引
如果应用程序有很多JOIN 查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。
而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样)