MySQL 优化

Mysql优化
  总的来说就是尽量提高索引的利用率,和减少全表扫描
  尽量拆分查询,在程序中处理,一般不要过多连表
  链接查询一般都是用左小表链接右大表,看情况用左链接还是内连接
  利用redis进行缓存,并提高缓存命中
  使用explain进行检查
    检查索引使用情况,尽量将条件放入索引中,并尽量保证输出见过全部被索引覆盖,
  exists 效率高于 in 可以更好的用到索引
  对于连续的数值,能用between就不要用in
  group by 只有一个表中的列,才会走索引
     limit 10000,10
          实际上是mysql查找到前10010条数据,之后丢弃前面的10000行,这个步骤的数据其实是浪费掉的.

    用查询条件进行替代: 比如 ID,用覆盖索引优化 select *  from (select id from job limit 1000000,100) a  left join job b on a.id = b.id; 查询一次ID子表,再进行连表
  where 中 尽量不要使用 判空 !=和<> or,会进行全表放弃索引

 

优化查询过程中的数据访问
  访问数据太多导致查询性能下降
  确定应用程序是否在检索大量超过需要的数据,可能是太多行或列
  确认MySQL服务器是否在分析大量不必要的数据行
  避免犯如下SQL语句错误
   查询不需要的数据。解决办法:使用limit解决
  多表关联返回全部列。解决办法:指定列名
  总是返回全部列。解决办法:避免使用SELECT *
  重复查询相同的数据。解决办法:可以缓存数据,下次直接读取缓存
  是否在扫描额外的记录。解决办法:
  使用explain进行分析,如果发现查询需要扫描大量的数据,但只返回少数的行,可以通过如下技巧去优化:
  使用索引覆盖扫描,把所有的列都放到索引中,这样存储引擎不需要回表获取对应行就可以返回结果。
  改变数据库和表的结构,修改数据表范式
  重写SQL语句,让优化器可以以更优的方式执行查询。
    
优化长难的查询语句
   一个复杂查询还是多个简单查询
  MySQL内部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢得多
  使用尽可能小的查询是好的,但是有时将一个大的查询分解为多个小的查询是很有必要的。
  切分查询,将一个大的查询分为多个小的相同的查询

  一次性删除1000万的数据要比一次删除1万,暂停一会的方案更加损耗服务器开销。
  分解关联查询,让缓存的效率更高。
  执行单个查询可以减少锁的竞争。
  在应用层做关联更容易对数据库进行拆分。
  查询效率会有大幅提升。
  较少冗余记录的查询
    
优化特定类型的查询语句
  count(*)会忽略所有的列,直接统计所有列数,不要使用count(列名)
  MyISAM中,没有任何where条件的count(*)非常快。
  当有where条件时,MyISAM的count统计不一定比其它引擎快。
  可以使用explain查询近似值,用近似值替代count(*)
  增加汇总表
  使用缓存


优化关联查询
  确定ON或者USING子句中是否有索引。
  确保GROUP BY和ORDER BY只有一个表中的列,这样MySQL才有可能使用索引。


优化子查询
  用关联查询替代


优化GROUP BY和DISTINCT
  这两种查询据可以使用索引来优化,是最有效的优化方法
  关联查询中,使用标识列分组的效率更高
  如果不需要ORDER BY,进行GROUP BY时加ORDER BY NULL,MySQL不会再进行文件排序。
  WITH ROLLUP超级聚合,可以挪到应用程序处理


优化LIMIT分页
  LIMIT偏移量大的时候,查询效率较低可以记录上次查询的最大ID,下次查询时直接根据该ID来查询

优化UNION查询
  UNION ALL的效率高于UNION

优化WHERE子句
  解题方法
    对于此类考题,先说明如何定位低效SQL语句,然后根据SQL语句可能低效的原因做排查,先从索引着手,如果索引没有问题,考虑以上几个方面,数据访问的问题,长难查询句的问题还是一些特定类型优化的问题,逐一回答。

SQL语句优化的一些方法?
  1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num isnull-- 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=
  3.应尽量避免在 where 子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描。
  4.应尽量避免在 where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num=10or num=20-- 可以这样查询:select id from t where num=10unionallselect id from t where num=20
  5.in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)-- 对于连续的数值,能用 between 就不要用 in了:select id from t where num between1and3
  6.下面的查询也将导致全表扫描:select id from t where name like ‘%李%’若要提高效率,可以考虑全文检索。
  7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:select id from t where num=@num-- 可以改为强制查询使用索引:select id from t with(index(索引名))where num=@num
  8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:select id from t where num/2=100-- 应改为:select id from t where num=100*2
  9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:select id from t where substring(name,1,3)=’abc’-- name以abc开头的id应改为:select id from t where name like ‘abc%’
  10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。    
    
    
    

posted @ 2023-04-20 13:12  外向孤独症_Xwb  阅读(7)  评论(0编辑  收藏  举报