建立索引

尽量避免全表扫描,首先应该考虑正在 where 及 order by 涉及的列上建立索引
在经常需要进行检索的字段上创建索引,创建索引给检索带来的性能往往是很大的,因此在发现检索速度太慢时应该考虑到创索引
一个表的索引最好不要超过6个,太多的话应该考虑一些不常使用到的列上是否有必要建立索引。索引不是说越多越好,索引虽然可以提高相应的 select 效率,但同时也减低了 insert 和 update 的效率,因为 insert 或 update 时有可能会重建索引

避免 null 值判断

应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描,如下:

select id from t where num is null

可以在num上设置默认值 0,确保表中num列没有null值,然后这样查询:

select id from t where num = 0

使用预编译查询

程序中通常是根据用户输入来动态执行SQL,这时应该尽量使用参数化SQL,这样不仅可以避免SQL注入的风险,最重要的是数据库会对这些参数化SQL进行预编译,第一次执行的时候DBMS会为这个SQL语句进行查询优化并执行预编译,这样以后再执行这个SQL的时候就直接使用预编译结果,可以大大提高执行效率

用where字句替换HAVING字句

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

尽量使用数字型字段

若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了

应拒绝使用 *

任何地方都不要使用select * from user,用具体的字段列表代替 " * ",不要返回用不到的任何字段

使用表的别名

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

用union all替换union

SQL语句需要union两个查询结果集合时,即使检索结果中不会有重复的记录,如果使用union这两个结果集 同样会尝试进行合并,然后在输出最终结果前进行排序,因此如果可以判断检索结果中不会有重复的记录时候,应该用union all,这样效率就会因此得到提高

尽量避免使用游标

因为游标的效率较差,如果游标操作的超数据过1万行,那么就应该考虑改写

update语句优化

只更改 1 到 2 个字段,就不要 update 全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志

delete语句优化语句

最高效的删除重复记录方法如下:

delete from num1 n1 where n1.id > (select min(n2.id) from num2 n2 where n2.username = n1.username)

insert语句优化

新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免造成大量日志,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后使用`insert。



本文作者: 博主:    文章标题:MySQL的SQL调优
本文地址:https://teamep.cn/81.html     
版权说明:若无注明,本文皆为“指间”原创,转载请保留文章出处。
最后修改:2020 年 07 月 28 日 10 : 52 AM
如果觉得我的文章对你有用,请随意赞赏