zoukankan      html  css  js  c++  java
  • MySQL 性能优化的最佳20多条经验分享

    http://blog.chinaunix.net/uid-20639775-id-154429.html   

    1. 为查询缓存优化你的查询 

    // 查询缓存不开启 
    $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()"); 
    
    // 开启查询缓存 
    $today = date("Y-m-d"); 
    $r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'"); 
    上面两条SQL语句的差别就是 CURDATE() ,MySQL的查询缓存对这个函数不起作用。所以,像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,
    因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。 

    2. EXPLAIN 你的 SELECT 查询 
    3. 当只要一行数据时使用 LIMIT 1 
    4. 为搜索字段建索引 
    5. 在Join表的时候使用相当类型的例,并将其索引 
    而且,这些被用来Join的字段,应该是相同的类型的。
    例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,
    MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样) 

    6. 千万不要 ORDER BY RAND() 
    7. 避免 SELECT * 
    从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。 
    8. 永远为每张表设置一个ID 
    9. 使用 ENUM 而不是 VARCHAR 
    11. 尽可能的使用 NOT NULL
    15. 固定长度的表会更快 
    如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。
    例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,
    那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。 
    16. 垂直分割 
    示例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,
      你并不需要经常读取或是改写这个字段。那么,为什么不把他放到另外一张表中呢? 这样会让你的表有更好的性能,
    大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。小一点的表总是会有好的性能。 

    示例二: 你有一个叫 “last_login” 的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。
    所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户 ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。 

    另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,
    不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。




    1、修改配置文件,windows下是my.ini,linux下是my.cnf;

    在配置文件的最后追加上:

     代码如下  

    query_cache_type = 1
    query_cache_size = 600000

    需要重启MySQL生效;

    那么采用第二种方式;

    b) 开启缓存,两种方式:

    a)使用mysql命令:

     代码如下  

    set global query_cache_type = 1;  
    set global query_cache_size = 600000;

    如果报错:

    query cache is disabled; restart the server with query_cache_type=1...

    在mysql命令行输入

    mysql> show variables like "%query_cache%"; 查看是否设置成功,现在可以使用缓存了;
    系统变量 have_query_cache 设置查询缓存是否可用 
    mysql> show variables like 'have_query_cache';

    系统变量 query_cache_size
    表示查询缓存大小,也就是分配内存大小给查询缓存,如果你分配大小为0,那么第一步和 第二步起不到作用,还是没有任何效果。

    mysql> select @@global.query_cache_size;
    上面是 mysql6.0设置默认的,之前的版本好像默认是0的,那么就要自己设置下。
    --设置global.query_cache_size这里是设置1M左右,900多K。
    mysql > set @@global.query_cache_size=1000000;

    query_cache_limit 控制缓存查询结果的最大值

    例如: 如果查询结果很大, 也缓存????这个明显是不可能的。

    MySql 可以设置一个最大的缓存值,当你查询缓存数结果数据超过这个值就不会进行缓存。缺省为1M,也就是超过了1M查询结果就不会缓存。

    mysql> select @@global.query_cache_limit;
    这个是默认的数值,如果需要修改,就像设置缓存大小一样设置,使用set重新指定大小。


    mysql查询缓存相关变量
    mysql> show variables like '%query_cache%';

    查看缓存的状态
    mysql> show status like '%Qcache%';

    MySQL 提供了一系列的 Global Status 来记录 Query Cache 的当前状态,具体如下:

    Qcache_free_blocks:目前还处于空闲状态的 Query Cache 中内存 Block 数目

    Qcache_free_memory:目前还处于空闲状态的 Query Cache 内存总量

    Qcache_hits:Query Cache 命中次数

    Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次数,也就是没有命中的次数

    Qcache_lowmem_prunes:当 Query Cache 内存容量不够,需要从中删除老的 Query Cache 以给新的 Cache 对象使用的次数

    Qcache_not_cached:没有被 Cache 的 SQL 数,包括无法被 Cache 的 SQL 以及由于 query_cache_type 设置的不会被 Cache 的 SQL

    Qcache_queries_in_cache:目前在 Query Cache 中的 SQL 数量

    Qcache_total_blocks:Query Cache 中总的 Block 数量

    检查查询缓存使用情况

    检查是否从查询缓存中受益的最简单的办法就是检查缓存命中率,当服务器收到SELECT 语句的时候,Qcache_hits 和Com_select 这两个变量会根据查询缓存的情况进行递增

    查询缓存命中率的计算公式是:Qcache_hits/(Qcache_hits + Com_select)。

    mysql> show status like 'Com_select%';

    query_cache_min_res_unit的配置是一柄”双刃剑”,默认是4KB,设置值大对大数据查询有好处,但如果你的查询都是小数据 查询,就容易造成内存碎片和浪费。

    查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%

    如果查询缓存碎片率超过20%,可以用FLUSH QUERY CACHE整理缓存碎片,或者试试减小query_cache_min_res_unit,如果你的查询都是小数据量的话。

    查询缓存利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%

    查询缓存利用率在25%以下的话说明query_cache_size设置的过大,可适当减小;查询缓存利用率在80%以上而且 Qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小,要不就是碎片太多。

    查询缓存命中率 = (Qcache_hits - Qcache_inserts) / Qcache_hits * 100%

    示例服务器 查询缓存碎片率 = 20.46%,查询缓存利用率 = 62.26%,查询缓存命中率 = 1.94%,命中率很差,可能写操作比较频繁吧,而且可能有些碎片

    引用一段前辈的话

    如果Qcache_lowmem_prunes 值比较大,表示查询缓存区大小设置太小,需要增大。
    如果Qcache_free_blocks 较多,表示内存碎片较多,需要清理,flush query cache
    关于query_cache_min_res_unit大小的调优,给出了一个计算公式,可以供调优设置参考:
    query_cache_min_res_unit = (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache

    参考链接: http://www.cnblogs.com/gimin/p/5459689.html

    
    



















  • 相关阅读:
    django 数据库内容管理(admin)
    django QuerySet的缓存机制(高效使用)
    Uniapp 离线打包
    idea启动Tomcat时控制台中文乱码问题
    windows 在服务中启动tomcat 配置jvm参数
    new File("E:") 文件路径变成项目所在的文件夹
    window10 开启ftp服务端
    MySQL没有默认my.ini文件
    mysql5.7 修改sql_mode配置
    一台服务器,多个Tomcat运行相同的系统,一个浏览器访问时cookie相互影响
  • 原文地址:https://www.cnblogs.com/maomaochong123/p/7042123.html
Copyright © 2011-2022 走看看