对mysql优化是一个综合性的技术,主要包括
a: 表的设计合理化(符合3NF)
b: 添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
c: 分表技术(水平分割、垂直分割)
d: 读写[写: update/delete/add]分离
e: 存储过程 [模块化编程,可以提高速度]
f: 对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]
g: mysql服务器硬件升级
h: 定时的去清除不需要的数据,定时进行碎片整理(MyISAM)
i: sql语句优化
本篇主要总结下索引有关内容
索引
四种索引(主键索引/唯一索引/全文索引/普通索引)
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name (index_col_name,...) index_col_name: col_name [(length)] [ASC | DESC] (列部分值作为索引)
列部分值作为索引::
对于CHAR和VARCHAR列,只用一列的一部分就可创建索引。
创建索引时,使用col_name(length)语法,对前缀编制索引。
前缀包括每列值的前length个字符。
BLOB和TEXT列也可以编制索引,但是必须给出前缀长度。
此处展示的语句用于创建一个索引,索引使用列名称的前10个字符。
CREATE INDEX part_of_name ON customer (name(10));
因为多数名称的前10个字符通常不同,所以此索引不会比使用列的全名创建的索引速度慢很多。
另外,使用列的一部分创建索引可以使索引文件大大减小,从而节省了大量的磁盘空间,有可能提高INSERT操作的速度。
前缀最长为255字节。对于MyISAM和InnoDB表,前缀最长为1000字节。
注意前缀的限长以字节计,而CREATE INDEX语句中的前缀长度指的是字符的数目。
对于使用多字节字符集的列,在指定列的前缀长度时,要考虑这一点。
在MySQL 5.1中:
· 只有当您正在使用MyISAM, InnoDB或BDB表类型时,您可以向有NULL值的列中添加索引。
· 只有当您正在使用MyISAM, BDB或InnoDB表类型时,您可以向BLOB或TEXT列中添加索引。
index_type::
部分储存引擎允许在创建索引时指定索引类型。
index_type指定语句的语法是USING type_name。
不同的储存引擎所支持的type_name值已显示在下表中。
如果列有多个索引类型,当没有指定index_type时,第一个类型是默认值。
存储引擎 | 允许的索引类型 |
MyISAM | BTREE |
InnoDB | BTREE |
MEMORY/HEAP | HASH, BTREE |
主键索引::
当一张表,把某个列设为主键的时候,则该列就是主键索引
1,create table testtable
(id int unsigned primary key auto_increment ,
name varchar(32) not null defaul '');
2,alter table 表名 add primary key (列名);
普通索引::
一般来说,普通索引的创建,是先创建表,然后在创建普通索引
比如:
create table ccc(
id int unsigned,
name varchar(32)
)
create index 索引名 on 表 (列1,列名2);
全文索引::
1,FULLTEXT索引只能对CHAR, VARCHAR和TEXT列编制索引,
2,在mysql中fulltext 索引只针对 myisam生效
3,mysql自己提供的fulltext针对英文生效->sphinx (coreseek) 技术处理中文
4,使用方法是 match(字段名..) against(‘关键字’)
5,全文索引一个 叫 停止词, 因为在一个文本中,创建索引是一个无穷大的数,
6,因此,对一些常用词和字符,就不会创建,这些词,称为停止词.
7,任何过于短的词都会被忽略。 全文搜索所能找到的词的默认最小长度为 4个字符。
8,MATCH()列列表必须同该表中一些 FULLTEXT索引定义中的列列表完全符合,除非MATCH()在IN BOOLEAN MODE(布尔全文搜索)。
9,对AGAINST() 的参数必须是一个常数字符串。
创建 :
CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) )engine=myisam charset utf8;INSERT INTO articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'), ('How To Use MySQL Well','After you went through a ...'), ('Optimizing MySQL','In this tutorial we will show ...'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL vs. YourSQL','In the following database comparison ...'), ('MySQL Security','When configured properly, MySQL ...');
如何使用全文索引:
错误用法:
select * from articles where body like '%mysql%'; [不会使用到全文索引]
证明:
explain select * from articles where body like '%mysql%'
正确的用法是:(match中的列值,跟定义fulltext时的一样)
select * from articles where match(title,body) against('database'); 【可以】
唯一索引::
①当表的某列被指定为unique约束时,这列就是一个唯一索引
create table ddd(id int primary key auto_increment , name varchar(32) unique);
这时, name 列就是一个唯一索引.
②在创建表后,再去创建唯一索引
create table eee(id int primary key auto_increment, name varchar(32));
create unique index 索引名 on 表名 (列表..);
unique字段可以为NULL,并可以有多NULL, 但是如果是具体内容(例如 ''),则不能重复.
主键字段,不能为NULL,也不能重复.
索引查询,删除,修改::
desc 表名 【该方法的缺点是: 不能够显示索引名.】
show index(es) from 表名
show keys from 表名
alter table 表名 drop index 索引名;
先删除,再重新创建.
索引使用的注意事项::
1.占用磁盘空间
2.对DML操作有影响,变慢(例如增加,删除,修改),因数据库操作中select占绝大部分,所以能有索引的地方最好还是用索引
例如:alter table dept add index my_ind (dname,loc); // dname 左边的列,loc就是右边的列
3,对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用。
explain select * from dept where loc='aaa'/G
就不会使用到索引
4,对于使用like的查询,查询如果是 '�a' 不会使用到索引,'aaa%' 会使用到索引。
比如: explain select * from dept where dname like '�a'/G
不能使用索引,即,在like查询时,关键的 ‘关键字’ , 最前面,不能使用 % 或者 _这样的字符.,
如果一定要前面有变化的值,则考虑使用 全文索引->sphinx.
5.如果条件中有or,即使其中有条件带索引也不会使用。
换言之,就是要求使用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字
select * from dept where dname=’xxx’ or loc=’xx’ or deptno=45
6.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。
否则不使用索引。(添加时,字符串必须''), 也就是,如果列是字符串类型,就一定要用 '' 把他包括起来.
7.如果mysql估计使用全表扫描要比使用索引快,则不使用索引。(有但少见,例如表中就一条数据)
适合创建索引的列应满足::
a: 肯定在where条经常使用
b: 该字段的内容不是唯一的几个值(sex:男或女 0或1)
c: 字段内容不是频繁变化.
查看索引使用的情况::
show status like 'Handler_read%';
结果中
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。
handler_read_rnd_next:这个值越高,说明查询低效。