面试官问:SQL如何优化,接招……

导读:本篇文章讲解 面试官问:SQL如何优化,接招……,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

面试官:SQL如何优化

答:

1.尽量少join

(可以通过在程序中将多个表中间结果进行操作,达到想要的效果)。

2.尽量少用排序

太消耗cpu:不必要的话不要排序。利用索引排序(选择查询的字段进行排序)。尽量对更少的字段排序。

3.尽量少用select *

(用什么取什么)

4.尽量用 join 代替子查询

(相比于子查询,join的性能要好一些
虽然 Join 性能并不佳,但是和 MySQL 的子查询比起来还是有非常大的性能优势。)。

5.对于相关子查询

(有时可以通过派生表来进行重写,以避免子查询与外部子查询的多次比较操作)。

6.尽量少用or

(mysql优化器对or没有太好的优化,可以使用IN、union 或 union all 代替or)。

7.尽量早过滤

(将过滤效果更好的条件判断放到前面)。

8.避免类型转换

(类型转换需要消耗cpu,所以,在数据库设计的时候尽量将一些列属性的类型设计的更加合理)。

9.count(1)和count(primary_key) 优于 count(*)

10.尽量把字段设置为NOT NULL

11.多表关联查询时,小表在前,大表在后

(在MySQL中,执行 from 后的表关联查询是从左往右执行的(Oracle相反),第一张表会涉及到全表扫描,所以将小表放在前面,先扫小表,扫描快效率较高,在扫描后面的大表,或许只扫描大表的前100行就符合返回条件并return了。)

12.使用表的别名

(当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个列名上。这样就可以减少解析的时间并减少哪些友列名歧义引起的语法错误。)

13.用where字句替换HAVING字句

(避免使用HAVING字句,因为HAVING只会在检索出所有记录之后才对结果集进行过滤,而where则是在聚合前刷选记录,如果能通过where字句限制记录的数目,那就能减少这方面的开销。HAVING中的条件一般用于聚合函数的过滤,除此之外,应该将条件写在where字句中。

where和having的区别:where后面不能使用组函数)

14.调整Where字句中的连接顺序

(MySQL采用从左往右,自上而下的顺序解析where子句。根据这个原理,应将过滤数据多的条件往前放,最快速度缩小结果集。)

如何避免不走索引的场景?

1.尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描

SELECT * FROM t WHERE username LIKE '%龙%'

优化方式:尽量在字段后面使用模糊查询。

SELECT * FROM t WHERE username LIKE '龙%'

2.尽量避免使用 or,会导致数据库引擎放弃索引进行全表扫描。

SELECT * FROM t WHERE id = 1 OR id = 3

优化方式:可以用union代替or。

SELECT * FROM t WHERE id = 1
   UNION
SELECT * FROM t WHERE id = 3

3.尽量避免进行null值的判断,会导致数据库引擎放弃索引进行全表扫描。

SELECT * FROM t WHERE score IS NULL

优化方式:可以给字段添加默认值0,对0值进行判断。

SELECT * FROM t WHERE score = 0

4.查询条件不能用 <> 或者 !=

使用索引列作为条件进行查询时,需要避免使用<>或者!=等判断条件。如确实业务需要,使用到不等于符号,需要在重新评估索引建立,避免在此字段上建立索引,改由查询条件中其他索引字段代替。

5.尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描。

可以将表达式、函数操作移动到等号右侧。

-- 全表扫描
SELECT * FROM T WHERE score/10 = 9
-- 走索引
SELECT * FROM T WHERE score = 10*9

6.隐式类型转换造成不使用索引

SQL语句由于索引对列类型为varchar,但给定的值为数值,涉及隐式类型转换,造成不能正确走索引。

select col1 from table where col_varchar=123; 

order by 条件要与where中条件一致,否则order by不会利用索引进行排序

-- 不走age索引
SELECT * FROM t order by age;
 
-- 走age索引
SELECT * FROM t where age > 0 order by age;

对于上面的语句,数据库的处理顺序是:

第一步:根据where条件和统计信息生成执行计划,得到数据。

第二步:将得到的数据排序。当执行处理数据(order by)时,数据库会先查看第一步的执行计划,看order by 的字段是否在执行计划中利用了索引。如果是,则可以利用索引顺序而直接取得已经排好序的数据。如果不是,则重新进行排序操作。

第三步:返回排序后的数据。

内容不够充分,还望初学者看的尽兴。

望:君子豹变

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/114988.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!