一、查询优化
-
对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 和 order by 涉及的列上建立索引。
-
应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。如:
select id from table where num is null;复制代码
最好不要给数据库留 null, 尽可能的使用 not null 填充数据库。
备注:描述,评论之类的可以设置为 null, 其他的,最好不要设置为 null.
不要以为 null 不需要空间, 比如 :char(100)型,在字段建立时,空间就固定了,不管是否插入值(null 也包含在内),都是占用 100 个字符的,如果是 varchar 这样的变长字段,null 不占用空间。
可以在 num 上设置默认值 0,确保表中 num 列没有 null 值,然后这样查询:
select id from table where num = 0;复制代码
-
应尽量避免在 where 子句中使用 != 或 <> 操作符,否则引擎将放弃使用索引而进行全表扫描。
-
应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,如:
select id from table where num = 1 or name = 'admin';复制代码
可以这样查询:
select id from t where num = 10 union all select id from t where name = 'admin';复制代码
-
in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from table where num in(1,2,3);复制代码
对于连续的值,能用 between 就不要用 in 了:
select id from table num between 1 and 3;复制代码
很多时候 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)复制代码
-
下面的查询也将导致全表扫描:
select id from table where name like '%abc%';复制代码
若要提高效率,可以考虑全文检索。
全文检索:先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search) 。
-
如果在 where 子句中使用参数,也会导致全表扫描。因为 SQL 只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的。因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from table where num = @num;复制代码
可以改为强制查询使用索引:
select id from table with(index(索引名)) where num = @num;复制代码
-
应避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from table where num/2 = 100;复制代码
应该为:
select id from table where num = 100*2;复制代码
-
应尽量避免在 where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from table where substring(name,1,3) = 'abc' -- name 以 abc 开头的 id select id form table where datediff(day,createdate,'2018-03-26') = 0 -- '2018-03-26' -- 生成的id 复制代码
-
不要在 where 子句中的 “=” 左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
-
在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
-
select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
-
索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。
-
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
-
尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
-
任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。