第一篇是最基础,同样也是最重要的Sql语句的优化。就和炒菜一样,假如我们的原材料,例如青菜或者肉是坏了的,即便我们拥有手艺一流的厨子,品质保证的厨具,也不可能做出美味的佳肴。所以,不仅要有好厨师好厨具,更要有好原料!而我们今天要讲的就是美味佳肴的基本:原材料,也就是Sql语句!
常见的Sql语句优化主要有以下几种:
1. 避免SELECT * 查询;
一方面,若我们动态SQL列引用 ‘*’ ,数据库在解析的过程中,会将“*” 依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。另一方面,SELECT * 会将被查询表的全部字段(假如有30个字段)内容显示出来,即便可能我们仅仅需要的只有5个字段。尤其是在其他25个字段中还有text等类型的字段时,必然浪费了我们很多不必要的时间,查询出了很多不必要的数据。所以,最根本的,一定要避免SELECT *查询。
2. 嵌套查询和连接查询;
在一个SELECT语句的WHERE字句或HAVING字符中嵌套另一个SELECT语句的查询,称为嵌套查询。被嵌套的称为子查询,子查询还可以嵌套。但是我们应该尽量少使用嵌套查询,嵌套查询的效率要比连接查询低很多,而且在嵌套查询中,索引是不起作用的。
3. 建立索引;
对查询进行优化,应该避免全表扫描,首先应该考虑在where及order by涉及的列上建立索引(具体索引的使用会再以后的文章中专门讲述)。但是建立索引之后也不能掉以轻心的,我们还是需要注意我们的sql语句的编写,因为在以下这几种情况,引擎会放弃索引而进行全表扫描,换言之,我们建立的为了提高效率的索引就不起作用了,所以我们应该尽量避免以下这些情况:
a) 在where子句中使用!=或<>操作符;
b) 在where字句中对字段进行null值判断,如;
select id from t where score is null;
如果我们需要这种为空的判断,可以在score上设置默认值为0,确保表中score列没有null值,然后这样查询:
select id from t where score = 0;
c) 使用where.. or ..或者where.. and ..连接查询条件时,若or或者and两边所有列中有一列没有加索引,则所有索引不起作用
d) 使用like查询时,%在第一位置,如
select id from t where name like “%abc”;
4. 绝对不要轻易使用order by rand(),很可能导致mysql的灾难;
5. 使用批量插入
插入多条记录时,可以使用一条INSERT语句插入一条记录,也可以使用一条INSERT语句插入多条记录。
第一种情况:
INSERT INTO emp(id,name) VALUES (1,'suse');
INSERT INTO emp(id,name) VALUES (2,'lily');
第二种情况
INSERT INTO emp(id,name) VALUES (1,'suse'),(2,'lily');
当插入数据量大时,使用第二种情况会比第一次情况快很多,因为第二种情况明显减少了与数据库连接的次数。
最后说一说EXPLAIN和desc
6. 使用LOAD DATA INFILE批量导入
当需要批量导入数据时,如果能用LOAD DATA INFILE语句,就尽量使用。因为LOAD DATA INFILE语句导入数据的速度比INSERT语句快很多。导出亦然,可用OUTFILE时就用。
说到了sql语句的优化,顺便说一下关于数据库结构的优化吧。一个好的数据库设计方案对于数据库的性能常常起到事半功倍的效果。数据库结构的设计需要考虑数据冗余、查询和更新速度、字段的数据类型是否合理等多方面。
(1)将字段很多的表拆分成多个表
有时候有些字段使用频率很低或者字段的数据类型比较大,那么可以考虑垂直拆分的方法,把不常用的字段和大字段拆分出去;
(2)增加中间表
对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。
(3)增加冗余字段
设计数据库表时应尽量遵循范式理论,尽可能减少冗余字段,但是现今存储硬件越来越便宜,有时候查询数据的时候需要join多个表,这样在高峰期间会影响查询的效率,我们需要反范式而为之,增加一些必要的冗余字段,以空间换时间。这样做会增加开发的工作量和维护量,但是如果能换来可观的性能提升,这样做也是值得的
这是比较常用的几种sql语句和数据库设计的优化,暂时先说这么多,后续可继续补充~
说完Sql语句的优化,我们可以发现其中一大点就是索引了,在下一篇文中中,我将为大家详细介绍关于索引的使用!