y23335793 发表于 2018-10-2 09:38:58

优化 MYSQL 经验总结 tmp_table_size

  数据库连接突然增多到1000的问题
查看了一下,未有LOCK操作语句。但是明显有好多copy to tmp table的SQL语句,这条语读的时间比较长,且这个表会被加读锁,相关表的update语句会被排进队列。如果多执行几次这样的copyt to tmp table 语句,会造成更多的语句被阻塞。连接太多造成mysql处理慢。copy to tmp talbe 语句产生的原因是查询需要Order By 或者Group By等需要用到结果集时,参数中设置的临时表的大小小于结果集的大小时,就会将该表放在磁盘上,这个时候在硬盘上的IO要比内销差很多。所耗费的时间也多很多。另外Mysql的另外一个参数max_heap_table_size比tmp_table_size小时,则系统会把max_heap_table_size的值作为最大的内存临时表的上限,大于这个时,改写硬盘。 我们的mysql这两个参数为:tmp_table_size 33554432 (33.5M)max_heap_table_size 16777216 (16.7M)比较小。建议增加到上百M。我们的内存应该够吧。 另外join_buffer_size(影响 表之间join性能的缓存)为131072 (131K)较小,可以增加一点。 # vi /etc/my.cnf  
  tmp_table_size=200M
  mysql> show processlist;

  mysql> show columns from wp_posts; SQL 语句的第一个 LEFT JOIN ON 子句中: LEFT JOIN _myuser AS t3 ON t1.userid=t3.userid  _mydata 的 userid 被参与了条件比较运算。为 _mydata 表根据字段 userid 建立了一个索引: mysql>>  mysql 的配置文件中,tmp_table_size 的默认大小是 32M。如果一张临时表超出该大小,MySQL产生一个 The table tbl_name is full 形式的错误,如果你做很多高级 GROUP BY 查询,增加 tmp_table_size 值。 这是 mysql 官方关于此选项的解释:
  tmp_table_size

  This variable determines the maximum>  对 WHERE, JOIN, MAX(), MIN(), ORDER BY 等子句中的条件判断中用到的字段,应该根据其建立索引INDEX。
  索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行。表越大,花费时间越多。如果表对于查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要考虑所有数据。如果一个表有1000行,这比顺序读取至少快100倍。所有的MySQL索引(PRIMARY、UNIQUE和INDEX)在B树中存储。
  根据 mysql 的开发文档:
  索引 index 用于:
  快速找出匹配一个WHERE子句的行
  当执行联结(JOIN)时,从其他表检索行。
  对特定的索引列找出MAX()或MIN()值
  如果排序或分组在一个可用键的最左面前缀上进行(例如,ORDER BY key_part_1,key_part_2),排序或分组一个表。如果所有键值部分跟随DESC,键以倒序被读取。
  在一些情况中,一个查询能被优化来检索值,不用咨询数据文件。如果对某些表的所有使用的列是数字型的并且构成某些键的最左面前缀,为了更快,值可以从索引树被检索出来。
  假定你发出下列SELECT语句:
  mysql> select * FROM tbl_name WHERE col1=val1 AND col2=val2;如果一个多列索引存在于col1和col2上,适当的行可以直接被取出。如果分开的单行列索引存在于col1和col2上,优化器试图通过决定哪个索引将找到更少的行并来找出更具限制性的索引并且使用该索引取行。
  一般动态设置tmp_table_size的大小的时候,要使用:
set global tmp_table_size=64*1024*1024  而不是:
set global tmp_table_size=64M  否则就会出现错误:
#1232 - Incorrect argument type to variable 'tmp_table_size'
页: [1]
查看完整版本: 优化 MYSQL 经验总结 tmp_table_size