上篇文章介绍了MySQL的结构和几种常用存储引擎,在平时学习和工作中,InnoDB和MyISAM用的比较多,InnoDB支持事务,支持行级锁,而MyISAM不支持事务,支持表级锁。在后续锁讲解中,可以了解到InnoDB存储引擎偏向于行级锁,开销大,加锁慢,并且会出现死锁的情况,锁定粒度最小,发生锁冲突的概率最低,并发最高;MyISAM存储引擎偏向于表锁,开销小,加锁快,不会出现死锁的情况,锁定粒度最大,发生锁冲突的概率最高,并发最低,锁的只是我们后续再学习,本篇文字我们主要分为三部分:一是MySQL索引概念和建立索引的优势,二是七中join理论,三是分析SQL性能下降的原因。
从宏观的角度看索引是帮助MySQL高效获取数据的一种数据结构,也可以理解为是排好序的快速查找的数据结构。
从字面意思理解:比如我们要在字典中查找某一个汉字,为了快速查找到,需要从字典的目录开始检索,所以索引对于数据库来说就是数据的目录而已。
这是MySQL的最基本索引,在整个MySQL架构中没有做任何限制,直接在table中某个字段建立索引即可,这也是我们平时工作中用的最多、最常见的。
--- 查询表中是否建立索引
show index from table_name;
--- 使用create语句创建索引
create index index_name on table(column_name(length));
--- 使用alter语句创建索引
alter table table_name add index index_name on (column_name(length));
--- 在创建表的时候创建索引
create table `table_name`(
`id` INT(11)NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`create_time` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY(`id`),
index index_name(column_name(length))
)
--- 删除索引
drop index index_name on table_name;
与普通索引类似,唯一的区别就是:索引列的值必须唯一,所以唯一索引一般是主键。如果是组合索引,则列值的组合必须唯一,创建方法和普通索引类似。
--- 使用create语句创建
create unique index index_name on table_name(column_name(length));
--- 使用alter语句创建
alter table table_name add unique index_name on(column_name(length));
--- 创建表时创建索引
create table `table_name`(
`id` INT(11)NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`create_time` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY(`id`),
unique index_name(column_name(length))
)
MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于 MyISAM 表;他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或CREATE INDEX被添加。对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。
-- 使用create语句创建
create FULLTEXT index index_name on table_name(column_name);
--- 使用alter语句创建
alter table table_name add FULLTEXT index_name on(column_name);
--- 创建表时创建索引
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
FULLTEXT (content)
);
平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。例如上表中针对title和time建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。
--- 使用alter语句创建
alter table table_name add index index_name ( `column1`, `column2`, `column3` )
--- 使用create语句创建
create index index_name on table_name(`column1`,`column2`,`column3`...);
索引的选择性是指索引列中不同值的数目与表中记录数的比,如果一个表中有2000条记录,表索引列有1900个不同的值,那么这个索引的选择性就是1900/2000=0.95。一个索引的选择性越接近于1,这个索引的效率就越高。
(1)通过建立唯一索引,可以保证数据库表中每一行数据的唯一性;
(2)类似于大学图书馆的图书类目,提高了数据检索效率,降低了数据库的IO成本;
(3)通过索引列对数据进行排序,降低了数据排序的成本,降低了CPU的消耗;
(4)可以加速表与表之间的连接,在实现数据参照完整性特别有意义;
(5)通过使用索引,可以在查询过程中使用优化隐藏器,提高数据库服务器性能。
(1)实际上索引也是一张数据表,该表保存了主键和建立了索引的字段,并且指向实体表的记录,所以索引列也是占用空间的,虽然大大提高了查询效率,同时却会降低更新表记录的速度;
(2)如对表进行INSERT、UPDATE、DELETE操作时,MySQL不仅要更新保存数据,还要保存一下索引文件,每次还要更新建立索引的字段。
(1)主键自动建立唯一索引;
(2)频繁作为查询条件的字段应建立索引;
(3)查询中与其他表关联的字段,外键应建立索引;
(4)单值、复合索引的选择问题(在高并发的情况下选择复合索引);
(5)查询中排序的字段,排序字段若通过索引去访问,会大大提高排序速度;
(6)查询中统计或者分组字段适合建立索引。
(1)表记录较少的情况下不适合建立索引;
(2)频繁更新的字段不适合去建立索引,因为每次不仅更新记录,还会更新索引字段;
(3)where条件里用不到的字段不适合创建索引;
(4)经常增删改的表字段,建立索引可以提高查询效率,但是会降低了更细表的速度,如对表进行INSERT、UPDATE和DELETE操作时,因为进行以上操作时,MySQL不仅要保存数据,还要保存索引文件,这样就降低了数据库服务器性能;
(5)如果某个数据列包含许多重复的内容,为它建立索引没有大大的实际效果;
(6)数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的字段建立索引。
(1)CPU:CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据的时候;
(2)IO:磁盘I/O瓶颈发生在装入数据远大于内存容量的时候;
(3)服务器硬件的性能瓶颈:top、free、iostat、vmstat来查看系统的性能状态。
select from TableA A inner join TableB B on A.key = B.key;
select from TableA A left join TableB B on A.key = B.key;
select from TableA A right join TbaleB B on A.key = B.key;
select from TabkleA A left join TableB B on A.key = B.key where B.key is null
select from TableA A right join TableB B on A.key = B.key where A.key is null;
select from TableA A FULLouter join TableB B on A.key = B.key;
select from TableA A FULL outer join TableB B on A.key = B.key where A.key is null or B.key is null;
(1)查询语句写的烂,查询尽量避免使用*,使用字段名代替*;
(2)索引失效;
(3)查询关联太多JOIN;
(4)服务器调优以及各个参数的设置。
本篇文章主要从什么是索引、怎么建立索引、索引分类和MySQL的七种JOIN查询来展开。索引在工作中非常重要,SQL的优化和服务器的调优、各项参数的设置对数据库服务来说很关键,通过这篇文章希望能够给大家带来便利,下片文章主要介绍SQL优化,写的不好的地方望大家多提意见,我洗耳恭听,虚心接受改正。