• 表锁定查询

    SHOW STATUS LIKE 'table%'
    
  • 行锁定查询

    SHOW STATUS LIKE 'innodb_row_lock%
    | Variable_name     | Value     |
    | :------------- | :------------- |
    | Innodb_row_lock_current_waits       | 0       | # 当前正在等待锁定的数量
    | Innodb_row_lock_time                | 490578  | # 从系统启动到现在锁定总时间长度
    | Innodb_row_lock_time_avg            | 37736   | # 每次等待所花平均时间(重要)
    | Innodb_row_lock_time_max            | 121511  | # 从系统启动到现在等待最长的一次所花的时间
    | Innodb_row_lock_waits               | 13      | # 从系统启到到现在总共等待的次数(重要)
    
  • EXPLAIN [Query语句]

    *************************** 1. row ***************************
           id: 1
    select_type: SIMPLE
    # 所使用的查询类型,主要有以下几种
    # DEPENDENT SUBQUERY: 子查询内层的第一个SELECT,依赖于外部查询的结果集.
    # DEPENDENT UNION: 子查询中的UNION,且为UNION中从第二SELECT开始的后面所有的SELECT,同样依赖于外部查询的结果集。
    # PRIMARY: 子查询中的最外层查询,注意并不是主键的查询。
    # SIMPLE: 除子查询或UNION之外的其它查询。
    # SUBQUERY: 子查询内层查询的第一个SELECT,结果不依赖于外部查询结果集。
    # UNCACHEABLE SUBQUERY: 结果集无法缓存的子查询。
    # UNION: UNION语句中第二个SELECT开始后面的所有SELECT,第一个SELECT为PRIMARY。
    # UNION RESULT:UNION 中的合并结果。
        table: cfm_account
         type: ALL
    # all:全表扫描
    # const: 读常量,最多只会有一条记录匹配,由于是常量,实际上只须读一次。
    # eq_ref: 最多只会有一条匹配结果,一般是通过主键或者唯一键索引来访问。
    # fulltext: 进行全文索引检索。
    # index: 全索引扫描。
    # index_merge: 查询中同时使用两个(或者多个)索引,然后对索引结果进行合并,再读取表数据。
    # index_subquery: 子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或者唯一索引。
    # rang:索引范围扫描。
    # ref:Join语句中被驱动表索引引用的查询。
    # ref_or_null:与ref的唯一区别就是在使用索引引用的查询之外再增加一个空值的查询。
    # system:系统表,表中只有一行数据。
    # union_subquery: 子查询中的返回结果字段组合是主键或者唯一的约束。
    #      
    possible_keys: NULL
    # 该查询可以利用的索引。如果没有任何索引可以使用,就会显示成null,这项内容对优化索引时的调整非常重要。
          key: NULL
    # Mysql query optimizer 从 possible_keys 中所选择使用的索引。        
      key_len: NULL
    # 被选中索引键长度。
          ref: NULL
    # 列出是通过常量(const),还是某个表某个字段(如果是join)来过虑(通过key)的.
         rows: 4276
    # 结果集记录条数。
        Extra:
    # Distinct:
    # Full scan on NULL key:
    # Impossible WHERE noticed after reading const table:Mysql query optimizer 通过收集到的统计信息判断出不可能存在结果。
    # No tables: query 语句中使用FROM DUAL 或不包含任何FROM子句。
    # Not exists: 在某些左连接中,mysql query optimizer 通过改变原有query的组成而使用的优化方法,可以部分减少数据访问次数。
    # Range Cached for each record: 通过Mysql官方手册的描述,当mysql query optimizer没有发现好的可以使用的索引时,如果发现前面表的列值已知,部分索引可以使用。
    #                               对前面表的每个行组合,mysql检查是否可以使用range或者index_merge访问方法来索取行。
    # SELECT tables optimizer away: 当我们使用某些聚合函数来访问存在索引的某个字段时,mysql query optimizer 会通过索引直接一次定位到所需的数据行完成整个查询。
                                  当然,前提是在query中不能有group by操作。如果使用Min()或者MAX()的时候。
    # Using filesort: 当query中包含order by 操作,而且无法利用索引完成排序操作的时候,mysql query optimizer 不得不选择相应的排序算法来实现。
    # Using index: 所需数据只需在index即可全部获得,不需再到表中取数据。
    # Using index for group-by:数据访问和Using index 一样,所需数据只须要读取索引,当query中使用group by 或者distinct子句时,如果分组字段也在索引中,extra中的信息就会是using index for group-by
    # Using temporary:当mysql在某些操作中必须使用临时表时,在extra信息就会出现using temporary。主要常见于group by 和order by 等操作中.
    # Using where: 如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现using where信息。
    # Using where with pushed condition: 这是一个仅仅在NDBCluster存储引擎中才会出现的信息,而且须要通过打开condition pushdown优化功能才可能被使用。控制参数为engine_condtion_pushdown.
    #      
    1 row in set (0.00 sec)
    
  • Profiling 的使用 >SET profileing=1; #开启Query profileing功能
    >SELECT ...
    >SHOW profiles; # 显示每条Query的概要信息.
    >SHOW profile cpu,block io for query ID; #查看具体的某条query详情.

  • 索引的优势。
    >1. 提高检索效率,加快检索时间,降低检索过程须要读取的数据量。 >2. 降低数据排序成本。

  • 索引的弊端 >1. 占用额外的存储空间。 >2. 带来额外的IO量与计算量,因此会消耗额外的系统资源。

  • 索引场景 >1. 较频繁的作为查询条件的字段应该创建索引。 >2. 唯一性太差的字段不适合单独创建索引,即时频繁作为查询条件。 >3. 经常更新的字段不适合创建索引。 >4. 不会出现在WHERE子句中的字段不该创建索引。

  • Innodb中主键索引取数据为何比其它的B-Tree索引取数据要快? >B-Tree即Balance Tree,数据都存放在Leaf node(叶节点),任何一个叶节点的长度都完全一样。
    >主键索引的叶节点直接存放的是数据本身,其它索引存放的只是主键的信息,最终还是指向主键索引,
    >因此主键索引自然要比其它索引快。

  • Hash 索引主要应用在Memory与NDBCluster存储引擎中.

  • Full-text 索引主要用来替换效率低下的LIKE '%****%'

  • 当索引失效时,强制使用索引。 > force index (index_name)

  • 有时候,在php或者其它语言中,查询记录时,有时可能我们只需要查询一条。

    $result = mysql_query("select * from `{users}`  order by id desc");
    mysql_fetch_array($result);
    

    以上为未优化的代码,目的只是为了取表中的一条记录,当表数据量大时,这条未经优化的代码将 给系统带来灾难性的后果,以下是优化后的结果:

    $result = mysql_query("select name,email from `{users}`  order by id desc limit 0,1");
    mysql_fetch_array($result);
    

    需要什么则取什么,这样,当mysql与应用不在同一服务器时能大大减少服务器之间的传输流量。 而后面的 limit 0,1则更为重要,防止了全表索引带来的性能影响。

  • Using temporary ; Using filesort 语句优化. 默认情况下,MySQL对所有GROUP BY col1,col2...的字段进行排序。这与在查询中指定ORDER BY col1,col2...类似。因此,如果显式包括一个包含相同的列的ORDER BY子句,则对MySQL的实际执行性能没有什么影响。 如果查询包括GROUP BY 但用户想要避免排序结果的消耗,则可以指定ORDER By NULL禁止排序,例如:

    explain select id, sum(moneys) from sales2 group by id \G
    explain select id, sum(moneys) from sales2 group by id order by null \G
    

    你可以通过比较发现第一条语句会比第二句在Extra:里面多了Using filesort.而恰恰filesort是最耗时的。