mysql优化基础

惟一索引(unique index)
强调惟一,就是索引值必须惟一。mysql

create unique index [索引名] on 表名 (列名);
alter table 表名 add unique index [索引名] (列名);
删除索引:
drop index 索引名 on 表名;
alter table 表名 drop index 索引名;程序员


主键
主键是一种特殊的惟一索引,主键要求建表时指定,通常用auto_increment列,关键字是primary keysql

creat table test2 (id int not null primary key auto_increment);数据库


全文索引
InnoDB不支持,MyISAM支持性能比较好,通常在 CHAR、VARCHAR 或 TEXT 列上建立。缓存

Create table 表名( 
id int not null primary key anto_increment,
title varchar(100),FULLTEXT(title)
)type=MyISAM;服务器


单列索引(普通索引)与多列索引(复合索引)
复合索引要注意"最左前缀原则"
"左前缀原则":在使用多列索引的时候 where中必须首先使用第一个索引(uname) 而后第二个(password) 第三个(..)
好比where uname="admin" and password="abc"
如下使用均起到到索引的效果:
where password="abc"
where password="abc" and uname="admin"
where uname="admin" or password="abc" (出现or则扫描全表)
create table test3 (
id int not null primary key auto_increment,
uname char(8) not null default '',
password char(12) not null,
INDEX(uname,password)
)type=MyISAM;
注意:INDEX(a, b, c)能够当作a或(a, b)的索引来使用,但不能看成b、c或(b,c)的索引来使用。这是一个最左前缀的 优化方法,在后面会有详细的介绍,你只要知道有这样两个概念。并发

聚簇索引性能

一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序。 聚簇索引肯定表中数据的物理顺序。Mysql中MyISAM 表是没有聚簇索引的,innodb有(主键就是聚簇索引)测试


查看表索引
show index from tableName;优化

表数据类型选择
1.能小就用小。表数据类型第一个原则是:使用能正确的表示和存储数据的最短类型。这样能够减小对磁盘空间、内存、cpu缓存的使用。
2.避免用NULL,这个也是网上优化技术博文传的最多的一个。理由是额外增长字节,还有使索引,索引统计和值更复杂。不少还忽略一 个count(列)的问题,count(列)是不会统计列值为null的行数。
3.Tinyint、smallint、mediumint、int、bigint,分别须要八、1六、2四、3二、64。 
值域范围:-2 (n-1)~ 2 (n-1)-1 
不少程序员在设计数据表的时候很习惯的用int,压根不考虑这个问题 
笔者建议:能用tinyint的毫不用smallint 
误区:int(1) 和int(11)是同样的,惟一区别是mysql客户端显示的时候显示多少位。 
整形优先原则:能用整形的不用其余类型替换,如ip能够转换成整形保存,如商品价格‘50.00元’则保存成50
4.精确度与空间的转换。在存储相同数值范围的数据时,浮点数类型一般都会比DECIMAL类型使用更少的空间。FLOAT字段使用4 字节存储 数据。DOUBLE类型须要8 个字节并拥有更高的精确度和更大的数值范围,DECIMAL类型的数据将会转换成DOUBLE类型。

建立一个表:
create table one (
id smallint(10) not null auto_increment primary key, 
username char(8) not null, 
password char(4) not null, 
`level` tinyint (1) default 0, 
last_login char(15) not null, 
index (username,password,last_login)
) engine=innodb;

分析sql语句执行状况:
explain 关键字

explain select * from one where last_login +1= 8388606 ; (错误用法)
explain select * from one where last_login = 8388607 ; (正确用法)
索引字段上使用表达式将失去索引效果


索引选择性

索引选择性是不重复的索引值也叫基数(cardinality)表中数据行数的比值,索引选择性=基数/数据行,基数能够经过 “show index from 表名”查看。高索引选择性的好处就是mysql查找匹配的时候能够过滤更多的行,惟一索引的选择性最佳,值为1。 那么对于非惟一索引或者说要被建立索引的列的数据内容很长,那就要选择索引前缀。这里就简单说明一下:

mysql> select count(distinct(username))/count(*) from one; 
+------------------------------------+ 
| count(distinct(username))/count(*) | 
+------------------------------------+ 
| 0.2047 | 
+------------------------------------+ 
1 row in set (0.09 sec) 
count(distinct(username))/count( )就是索引选择性,这里0.2过小了。假如username列数据很长,则能够经过 select count(distinct(concat(first_name, left(last_name, N))/count( ) from one;测试出接近1的索引选择性, 其中N是索引的长度,穷举法去找出N的值,而后再建索引。


系统配置与维护优化
重要的一些变量

key_buffer_size索引块缓存区大小, 针对MyISAM存储引擎,该值越大,性能越好.可是超过操做系统能承受的最大值,反而会使mysql变得不稳定. ----这是很重要的参数
sort_buffer_size 这是索引在排序缓冲区大小,若排序数据大小超过该值,则建立临时文件,注意和MyISAM_sort_buffer_size的区别----这是很重要的参数
read_rnd_buffer_size当排序后按排序后的顺序读取行时,则经过该缓冲区读取行,避免搜索硬盘。将该变量设置为较大的值能够大大改进ORDER BY的性能。可是,这是为每一个客户端分配的缓冲区,所以你不该将全局变量设置为较大的值。相反,只为须要运行大查询的客户端更改会话变量
join_buffer_size用于表间关联(join)的缓存大小
tmp_table_size缓存表的大小
table_cache容许 MySQL 打开的表的最大个数,而且这些都cache在内存中
delay_key_write针对MyISAM存储引擎,延迟更新索引.意思是说,update记录时,先将数据up到磁盘,但不up索引,将索引存在内存里,当表关闭时,将内存索引,写到磁盘


optimize、Analyze、check、repair维护操做

optimize 数据在插入,更新,删除的时候不免一些数据迁移,分页,以后就出现一些碎片,长此以往碎片积累起来影响性能, 这就须要DBA按期的优化数据库减小碎片,这就经过optimize命令。如对MyISAM表操做:optimize table 表名

对于InnoDB表是不支持optimize操做,不然提示“Table does not support optimize, doing recreate + analyze instead”, 固然也能够经过命令:alter table one type=innodb; 来替代。

Analyze 用来分析和存储表的关键字的分布,使得系统得到准确的统计信息,影响 SQL 的执行计划的生成。对于数据基本没有发生 变化的表,是不须要常常进行表分析的。可是若是表的数据量变化很明显,用户感受实际的执行计划和预期的执行计划不 同的时候, 执行一次表分析可能有助于产生预期的执行计划。Analyze table 表名
Check检查表或者视图是否存在错误,对 MyISAM 和 InnoDB 存储引擎的表有做用。对于 MyISAM 存储引擎的表进行表检查, 也会同时更新关键字统计数据
Repair optimize须要有足够的硬盘空间,不然可能会破坏表,致使不能操做,那就要用上repair,注意INNODB不支持repair操做


表结构的更新与维护

改表结构。当要在数据量千万级的数据表中使用alter更改表结构的时候,这是一个棘手问题。一种方法是在低并发低访问量的时 候用日常的alter更改表。另一种就是建另外一个与要修改的表,这个表除了要修改的结构属性外其余的和原表如出一辙,这样就 能获得一个相应的.frm文件,而后用flush with read lock 锁定读,而后覆盖用新建的.frm文件覆盖原表的.frm, 最后unlock table 释放表。
创建新的索引。通常方法这里不说。
建立没索引的a表,导入数据造成.MYD文件。
建立包括索引b表,造成.FRM和.MYI文件
锁定读写
把b表的.FRM和.MYI文件改为a表名字
解锁
用repair建立索引。
这个方法对于大表也是颇有效的。这也是为何不少dba坚持说“先导数据库在建索引,这样效率更快”

按期检查mysql服务器 按期使用show status、show processlist等命令检查数据库。这里就不细说,这提及来也篇幅是比较大的,笔者对这个也不是很了解

相关文章
相关标签/搜索