VVL1295

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  出现的条件:

    1,语句含有 order by 子句以及一个不同的 group by 子句,两个子句使用不同的索引;

    2,order by 或者 group by 子句使用了不是第一个表中的索引(连表查询);

    3,distinct 搭配 order by 可能会导致临时表出现;

    4,多表 update;

  临时表分为内存临时表,磁盘临时表,其中磁盘临时表的性能更加糟糕,其中,一下情况会引起磁盘临时表的产生:

    1,表中存在 BLOB 或者 TEXT;

    2,group by 或者 distinct 子句中存在大小超过 512 个字节的二进制字符串类型列,或者超过 512 个字符的非二进制字符串类型;(这是对于 5.7.5之前而言的,在5.7.3之前,限制为512个字节的任何类型的字符串类型);

    3,如果使用了 union 或者 union all,那么 select 里存在 max 大小超过512(对于二进制是512个字节,对于非二进制是512个字符),就会用上磁盘临时表;

  当结果需要进行类型转换,就会导致临时表的产生;

  符合以下条件的 union 不会用上磁盘临时表:

    1,使用 union all 不是 union 或者 union distinct;

    2,没有全局的 order by 子句;

    3,union 不在 select 语句的最顶级查询块中;

  临时表的使用:

    内部临时表会被内存存储引擎处理,或者被 innodb 或者 myisam 引擎存储在磁盘;

    如果一个内部临时表被建立在内存上,但是变得太大,MySQL 就会自动把它转换成磁盘连接表;内存临时表的所占内存的最大值决定于 tmp_table_size 和 max_heap_table_size 中更小的那个;

    上述的内部临时表不同于真实被创建的表附带的内存表,对于这些表,只有 max_heap_table_size 决定所占内存的最大值,而且不会储存在磁盘上;

    参数 internal_tmp_disk_storage_engine 决定了哪个数据库引擎把内部临时表存储在磁盘上,5.7.6 之前为 myisam,5.7.6 及之后为 innodb;

    使用 internal_tmp_disk_storage_engine=INNODB,如果产生临时表的语句超过 INNODB 限制得行或者列,会导致返回错误 Row size too large 或者 Too many columns ,解决办法就是将其参数值改为 MYISAM;

    只要临时表所需的内存大于 tmp_table_size 或者 max_heap_table_size,就需要转化成磁盘临时表,通常把 tmp_table_size 和 max_heap_table_size 设为同样大小;

    设置这两个值的大小的实践通常是,令95%或以上的临时表为内存临时表,可以监控表的情况,通过命令:show global status like 'Created';

    MySQL 无法显示这些临时表的大小,因为不同的查询语句对应的临时表的大小都不一样,两种办法,1,使用 Percona Server;2,把 extra 信息记录在 slow-query log;(都不清楚这两个办法如何实施)

    

posted on 2016-12-26 22:02  bobo2018  阅读(141)  评论(0)    收藏  举报