• MySQL性能优化之道


     1.in和not in子查询优化

    not in 是不能命中索引的,所以以下子查询性能很低。

    如果是确定且有限的集合时,可以使用。如 IN (0,1,2)。

    用 exists或 notexists代替

    select *  from test1  where EXISTS (select * from test2  where id2 = id1 )
    select *  FROM test1  where NOT EXISTS (select * from test2  where id2 = id1 )

    尽量用join代替

     select id1 from test1 INNER JOIN test2 ON id2 = id1 
     select id1 from test1 LEFT JOIN test2 ON id2 = id1  where id2 IS NULL

     2.模式匹配like '%xxx%'优化

    like 'xxx%可以用到索引,但是like '%xxx%却无法用到索引。

    EXPLAIN
    SELECT 书名 FROM cbbd WHERE 书名 LIKE '%人%'

    EXPLAIN
    SELECT 书名 FROM cbbd WHERE 书名 LIKE '人%'

     3.大表高效取分页数据

    SELECT * FROM cbbd a INNER JOIN (SELECT id FROM cbbd  LIMIT 800000,5) b ON a.id=b.id

    4.COUNT(*)统计函数如何加快速度

    在mysql 5.7中,对于select count(*) from table 的优化,可以设置为:

    select count(*) from table where uid>0

    其中uid为辅助索引,辅助索引不存放数据,而是有一个指针指向对应的数据块,因此速度更快;

    从实际业务角度优化:既然我们知道innodb引擎并不适合做 select count(*)查询,那么我们回过头来看看实际业务的需求是怎样的?

    select count(*) from cbbd

    采用这样的查询是因为需要查出实时参与活动的总人数,但是这里的“实时”是否一定要实时,采用准实时,用户会反感吗?或者即使有一定的偏差,普通用户能感知吗?如果我们得出答案,这个实时的参与数只要准实时,允许一定的偏差,那么就好办了:

    select id from  cbbd  order by id desc limit 1

    我们只要查最新的一条记录,id是自增字段,取当前的这个id值就可以大约知道总参与人数了(注意我们的项目里并不会删除参与记录)。

    5.or条件优化

    当使用or的时候是不会用到索引的

    SELECT * FROM aladdin_resource WHERE state = 1 OR state = 2;

    解决办法就是用union替换or

    select * from aladdin_resource where state=1 union select * from aladdin_resource where state=2;

    6.ON DUPLICATE KEY UPDATE

    mysql中高效的主键冲突处理,冲突则执行update,不冲突则执行insert

    注意:ON DUPLICATE KEY UPDATE只是MySQL的特有语法,并不是SQL标准语法! 

    IF (SELECT * FROM ipstats WHERE ip='192.168.0.1') {
        UPDATE ipstats SET clicks=clicks+1 WHERE ip='192.168.0.1';
    } else {
        INSERT INTO ipstats (ip, clicks) VALUES ('192.168.0.1', 1);
    }

    以上几行代码可以用以下一行代码取代

    INSERT INTO ipstats VALUES('192.168.0.1', 1) ON DUPLICATE KEY UPDATE clicks=clicks+1;

    7.去掉不必要的降序可以提升性能

    8.用where子句替换having子句

    9.合理使用索引

     合理使用单列所引和联合索引

     字段使用函数将不能使用索引

    10.致命的无引号导致全表扫描,无法用到索引

    11.

    12.

    13.

    14. Multi-Range Read 多范围读(MRR)

    MySQL 5.6版本提供了很多性能优化的特性,其中之一就是 Multi-Range Read 多范围读(MRR) , 它的作用针对基于辅助/第二索引的查询,减少随机IO,并且将随机IO转化为顺序IO,提高查询效率。

    相关参数

    我们可以通过参数 optimizer_switch 的标记来控制是否使用MRR,当设置mrr=on时,表示启用MRR优化。mrr_cost_based 表示是否通过 cost base的方式来启用MRR.如果选择mrr=on,mrr_cost_based=off,

    则表示总是开启MRR优化。参数read_rnd_buffer_size 用来控制键值缓冲区的大小。

    https://www.cnblogs.com/Terry-Wu/p/11609743.html

  • 相关阅读:
    P1439 【模板】最长公共子序列
    DP,入门???
    关于Eclipse在servlet中连接数据库时出现驱动加载失败的解决
    JSP学习(JavaBean)
    HTML随笔3
    CSS随笔3
    计算机网络随笔
    基本命令行操作1(java编译)
    Javascript随笔2(JQuery)
    Javascrip随笔1
  • 原文地址:https://www.cnblogs.com/cnki/p/8093333.html
Copyright © 2020-2023  润新知