日期:2014-05-16  浏览次数:20886 次

mysql 性能优化点记录
第一章
myisam,可以基于blob和text的前500字节,创建索引
myisam 支持fulltext
延迟更新索引
(delay_key_write)
CREATE TABLE `table3` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(30) DEFAULT NULL,
  `id2` INT(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)  ENGINE=MYISAM DEFAULT CHARSET=utf8  DELAY_KEY_WRITE = 1
ALTER TABLE table2 DELAY_KEY_WRITE = 1
只有myisam支持全文检索
第三章 索引方面
  字段尽可能的小
  尽量避免null,用0代替。但是对性能的提升很小,最后考虑,索引的列最好不适用null
 
mysql性能优化点记录
一、优化数据访问
查询性能低下的最基本原因就是访问了太多数据。一些查询不可避免的要筛选大量的数据,单这并不常见。大部分性能欠佳的查询都可以用减
少数据访问的方式进行修改。在分析性能欠佳的查询的时候,下面两个步骤比较有用:
1.应用程序是否在获取超过需要的数据。这通常是访问了过多的行或列。
2.mysql服务器是否分析了超过需要的行。
对于访问的数据行很大,而生成的结果中数据行很少,可以尝试修改。

1.使用覆盖索引,它存储了数据,所以存储引擎不会去完整的行。
2.更改架构,一个例子就是使用汇总表。
3.重写复杂的查询,让mysql的优化器可以优化的执行。

二、复杂查询和多个查询
1.把一个复杂的查询分解为多个简单的查询。(mysql一般的服务器,每秒钟可以处理50 000个查询)
2.
三、缩短查询
将一次处理大量数据的操作,分解为多个小操作。循环的方式每次处理一部分数据。一次删除不要超过10 000行(delete)
四、分解链接
把一个多表连接分解成多个单个查询,然后在应用程序里实现联接。
这样的优势
1.缓存效率高。
2.mysql,可以更有效的利用表锁,查询会锁住单个表较短时间。
3.应用程序进行联接可以更方便的拓展数据库,把不同表放在不同服务器上。
4.查询更高效。
5.可以减少多余的行访问,可以减少网络流量和内存消耗。
小结:在程序端进行联接的效率更高
1.可以缓存早期查询的大量数据。
2.使用了多个myisam表
3.数据分布在不同的服务器上。
4.对于大表使用in替换联接
5.一个连接引用了同一个表多次。

当你重建汇总和缓存表的时候,在操作的时候你常常需要它们的数据保持可见。你可以使用“shadow table”(影像表)来实现。当你已经创建它之后,你可以使用原子性的重命名来交换这些表。举个例子,如果
你需要重建my_summary,你能创建my_summary_new,填充数据,把它和真正的表作交换。
mysql> DROP TABLE IF EXISTS my_summary_new, my_summary_old;
mysql> CREATE TABLE my_summary_new LIKE my_summary;
-- populate my_summary_new as desired
mysql> RENAME TABLE my_summary TO my_summary_old, my_summary_new TO my_summary;

mysql执行查询的一般性过程
1.客户端发送查询到服务器
2.服务器检查查询缓存,
3.服务器解析,预处理和优化查询,生成执行计划。
4.执行引擎调用存储引擎api执行查询。
5.服务器将结果发送到客户端。

mysql客户端、服务器协议
1.协议是半双工的。mysql服务器在某个时间可以发送或者接受数据,单不能同时发送和接收。所有没有办法阶段消息。

2.客户端用一个数据包将查询发送到服务器,所以max_packet_size这个配置参数对于大查询很重要的原因。
3.客户端从服务器提取数据的时候是服务器产生数据的同时把它们“推”到客户端的,客户端只需要接收推出来的数据,无法告诉服务器停止
发送数据。

查询缓存

SELECT SQL_NO_CACHE * FROM ol_answerlog LIMIT 1000
SHOW STATUS LIKE 'last_query_cost'


关键字straight_join 强制执行引擎按照查询中表现的顺序来进行链接操作。
严格的说,mysql不回尝试减少读取的行数,它只会试着优化对页面的读取,但是行数可以大致显示查询的开销。
连接优化器试着产生最低开销的查询计划。在可能的时候,他会从单表计划开始,检查所有的可能的子树的组合。但是对n个表连接,需要检
查组合的数量就是n的阶乘,这个数量称为ie搜索空间, 它增长非常快,如果一个查询需要连接10个表,那么要检查的数量将是10!=36288000
当搜索空间非常巨大的时候优化耗费的时间就会非常长,这时候服务器就不回执行完整的分析,但表的数量超过optimizer_search_depth的值
时,它就会走捷径,比如执行所谓的 贪婪搜索。

SHOW TABLE STATUS FROM `servant_591up`WHERE ENGINE IS NOT NULL
AND NAME LIKE '%ol_ans%';

max min的优化
select min(id) from ol_user where username = 'dddd@dd.com'
(一)max 和 min 会扫描整张表。
mysql的主键都是按照升序排列的。
可以使用limit 改写查询,
select userid from ol_user where username='test@nd.com' limit 1
(二)对同一表进行select 和 update
mysql不允许对一个表进行update的时候进行select
update tb1 as out_table
set cnt = (select count(*) from tb1 as inner_table where inner_table.type = outer_table.type);
一个实现方式:衍生表,当成临时表来处理。
update tb1 inner join(
select type,count(*) as cnt
from tb1
group by type
)as der using(type)
set tb1.cnt = der.cnt;
(三、)优化特定类型的查询
1.count
count的作用 统计值的数量和统计行的数量
值是非空表达式(NOT NULL)
一个常见的错误就是在想统计行数的时候,在count的括号中放入列名,如果想知道结果的行数,应该总是使用COUNT(*),这可以清晰的说明意
图,并且得到好的性能。
2.MYISAM
只有在没有WHERE条件的时候COUNT(*)才是最快的,在有条件过滤的时候并不非常快。
3.简单优化
可以利用MYISAM对COUNT(*)的优化对已经有索引的一小部分做统计。
SELECT COUNT(*) FROM WORD.CITY WHERE ID>5;
优化为下面的语句
SELECT (SELECT COUNT(*) FROM CITY) - COUNT(*) FROM CITY WHEREID<=5;
这样的explain只扫描6行数据
使用一个查询统计同一列中不同值的数量。
select sum(if(color='blue',1,0)) as blue,sum(if(color='red',1,0)) as red from items;