mysql的sql语句的优化策略

mysql慢sql的查看:https://www.cnblogs.com/msi-chen/p/10885795.html#_label3
特别注意:索引跟出参也有相关联系

索引注意:是否能使用索引,取决于mysql查询优化器对统计数据分析后,是否认为使用索引更快。因此,单纯的讨论一条sql是否可以使用索引有点片面,还需要考虑数据。

一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变;理想状态约  5个左右。

SQL语句优化策略:

1、表的主键、外键必须有索引;
2、sql有个最左原则,字段离散率越高索引效率越好的原则(离散率低的都没有必要建索引)
3、经常与其他表进行连接的表,在连接字段上应该建立索引;
4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
5、索引应该建在选择性高的字段上;
6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:

     现在MySQL已经支持同时走多个单独的索引,如果使用联合索引,那么where条件也要尽量根据联合索引的顺序来
       A、正确选择复合索引中的主列字段,一般是选择性较好的字段;
       B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;
       C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
       D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
       E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
8、频繁进行数据操作的列(修改频繁),不要建立太多的索引;
9、删除无用的索引,避免对执行计划造成负面影响;
10、不要对数据库的字段进行函数处理 如:where  comments= #{comments}    前面一个comments属于数据库字段  后面#{comments} 是可以用函数处理的,但是前面的comments  数据库的字段是不能被函数处理的,否则不会走索引。

11、  in索引在主键的时候也会走索引

12、sql语句在大于或者大于等于的时候会走索引,但是在小于或者小于等于的时候没有走索引

个人经验: 

  个人经验:内连接时外键设为索引时 则 主表索引级别 eq_ref 若在外键的表建立索引此索引会失效
   所以 使用强制的主键索引  FORCE INDEX (PRI)
   联表时子句适当先用子句过滤数据也会提升几十倍的速度

   个人经验:左(右)连接 左表不走索引,但是如果在 GROUP BY pm.id(左表主键)
    若不是主键强制索引  FORCE INDEX (PRI)   则左表的索引为 index 类型
    若在where后跟上主键字段则两张表的索引类型都为const 

 

配置的优化策略

1、为了解决上面(1)的问题,采用延迟索引。"延迟关联" :通过使用覆盖索引查询返回需要的主键,
再根据主键关联原表获得需要的数据。

通过延迟关联解决(1)无法使用覆盖索引的问题,使其能够使用覆盖索引。
explain select * from article join (select comments from
 article where category_id=12) as t on t.comments=article.comments;

2、优化UNION查询。MySQL通过创建并填充临时表的方式来执行UNION查询,
因此需要手工的将where、limit、order by等子句“下推”到UNION的各个子查询中,
除非确实需要服务器消除重复的行,否则一定要使用UNION ALL,如果没有ALL关键字,
MySQL会给临时表加上distinct,从而对临时表的数据做唯一性检查,这样代价非常高。


3、优化关联查询,确保on或者using子句中的列上有索引。
确保group by和order by的表达式只涉及一个表中的列,
这样MySQL才有可能使用索引来优化整个过程。

4、优化group by和distinct。MySQL使用同样的方法优化这两类查询,
通常是利用索引的顺序性进行优化。但是如果无法使用索引,
group by使用两种策略来完成:使用临时表或者文件排序来做分组。

5、只有索引列顺序和order by子句的顺序完全一致,并且所有列的排序方向都一致时,MySQL才能使用索引来对结果做排序

6、使用索引覆盖扫描,把所有需要的列都放入索引,这样存储引擎无须回表获取对应行就可以返回结果;

7、优化MySQL的参数
    通过优化MySQL的参数可以提高资源利用率,从而达到提高MySQL服务器性能的目的。如下是一些该方面参数的介绍。该参数的配置信息都在my.cnf或者my.ini文件中。

    key_buffer_size:表示索引缓冲区的大小。所有线程共享缓冲区。增加索引缓冲区可以得到更好处理的索引。当然如果这个值太大,会导致操作系统频换换页,降低系统性能。
    table_cache:表示同时打开表的个数,该值越大能够同时打开的表的个数越多。如果打开表的个数太多会影响操作系统的性能。
    query_cache_size:查询缓冲区的大小。该值和query_cache_type配合使用。当query_cache_type=0,所有查询都不使用缓冲区,但是MySQL并不会释放query_cache_size所配置的缓冲区内存。当query_cache_type=1,所有查询使用缓冲区,除非在查询语句中指定SQL_NO_CACHE,如SELECT SQL_NO_CACHE * FROM table_name; 当query_cache_type=2,只有在查询语句中使用SQL_CACHE关键字,查询才会使用缓冲区。使用查询缓冲区可以提高查询速度,这种方式适用于修改操作少且经常执行相同的查询操作的情况。
    innodb_buffer_pool_size:表示InnoDB类型的表和索引的最大缓存,该值越大查询速度就会越快。
    max_connections:表示数据库的最大连接数。该值过大会浪费内存资源,严重可能会导致MySQL服务器僵死。
    sort_buffer_size:表示每个需要排序线程分配的缓冲区的大小。该值越大排序的速度越快。增加该值可以提高ORDER BY或 GROUP BY操作的速度。默认值为2M。

8、使用索引合并的案例
    https://blog.csdn.net/caomiao2006/article/details/52144964
    explain select * from test where (key1_part1=4 and key1_part2=4) or key2_part1=4\G     只有and 和or 同时出现时才会走复合索引  但是具体要看mysql分析器

9、Innodb行锁优化建议
    尽可能让所有的数据检索都通过索引来完成,从而避免Innodb因为无法通过索引键加锁而升级为表级锁定;
    合理设计索引,让Innodb在索引键上面加锁尽可能准确,尽可能的缩小锁定范围,避免造成不必要的锁定而影响其他Query的执行;
    尽可能减少基于范围的数据检索过滤条件,避免间隙锁带来的负面影响而锁定了不该锁定的记录;
    尽量控制事务的大小,减少锁定的资源量和锁定时间长度;
    在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少MySQL因为实现事务隔离级别所带来的附加成本;

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值