MySQL数据库优化相关知识:
一、两种常用引擎的选择
1、MyISAM
当MySQL版本小于5.5时的默认引擎
优点:擅长数据处理;高速读写;数据的存储顺序为插入顺序,插入速度快;空间占用量小
特性:全文索引支持(版本大于等于5.6的Innodb也支持),可以利用myisamPack完成数据的压缩功能
缺点:仅支持表级锁定,支持并发插入,写操作中插入操作不会影响其他操作。不支持事务
2、InnoDB
版本大于等于5.5的默认引擎
优点:提供事务,行级锁定,外键约束,注重数据的完整性和安全性
特点:事务,外键约束,维护数据完整性;擅长并发处理,支持行级锁定
缺点:数据按照主键的顺序进行存储,插入时做排序工作效率低
二、数据类型的选择原则
在满足需求的前提下:
1、数据尽可能的小,使占用的存储空间小
2、尽可能定长,使占用的存储空间固定,减少变长时计算带来的损耗
3、尽可能使用整数
三、常用手段:索引
1、概念
索引是利用关键字使记录的部分数据与记录位置有直接的对应关系
2、索引的类型
①主索引(primary key):要求关键字不能重复,也不能为NULL,同时添加主键约束
②唯一索引(unique index):要求关键字不能重复,同时添加唯一约束
③普通索引(index):对关键字没有要求
④全文索引(fulltext index):关键字的来源是从字段中提取的特别关键词
⑤复合索引,多个字段上提取关键字需要用到复合索引
3、添加索引
alter table table_name add {(primary key),(unique index),(index),(fulltext index)} index_name (‘字段名‘);
4、删除索引
alter table table_name drop {(primary key),(index)...} index_name;
tips:可以利用explain来获取查询语句的执行计划
5、使用场景
①索引检索:条件过滤的字段添加索引,如where,select
②索引排序:如order by
③索引覆盖:如where后面的字段已经在select后面多个字段中已经出现,只需要添加select后面字段的复合索引
6、使用规则
①列独立:索引字段需要保证 独立 在一侧
②左原则:匹配模式必须在左边确定不能以通配符开头,即 like 后面的条件不能以% _ 开头
③复合索引左规则:复合索引关联多个字段,where时仅对复合索引最左边的字段有效果
④OR的使用:需要保证OR两边的条件都存在可用的索引,该查询才会使用索引
⑤MySQL智能选择:查询使用索引会导致大量的随机IO,当随机IO大于顺序遍历IO时,会自动弃用该索引
⑥同时满足检索、排序和覆盖是最好的
7、前缀索引(建立索引关键字的一种方案,不能用于索引覆盖)
index `index_name` (`index_field`(N))使用index_field的前N个字符建立的索引
确定N的tips:
①计算最大辨识度:
select all_count/count(distinct 字段名) from table_name,越接近该值越接近极限
②计算前N个字符达到的辨识度:
select all_count/count(distinct substr(字段名, 1, N)) from table_name;依次增大N的值,达到最大辨识度时的N即可建立前N个字符建立的索引
8、全文索引
举个栗子,解决 like ‘%keyword%’这类查询的匹配问题
Select * from articles where title like ‘%database%’ or body like ‘%database%’;此时不能建立普通索引,查询不符合 左原则,建立了也使用不了。此时 全文索引就可以其作用了:
alter table articles add fulltext index `title_body` (`title`,`body`);
再使用Match()against()进行全文索引匹配语法才可以生效。本栗子中使用
select * from article where match(title, body) against(‘database‘);
注意:①不能对中文起作用;②类似 in a 等无具体意义的词不能用该方法,因为全文索引的是数据中提取的关键词
9、索引的数据结构(hash、B-Tree、聚集索引/聚簇索引)
四、查询缓存 query_cache
将select的查询结果存储起来供二次使用的缓存区域
开启方法:
①show variables like ‘query_cache%‘;
②set global query_cache_type = 1; //开启查询缓存
③set global query_cache_size = 1024*1024*32;//设置查询缓存为32M
注意:①查询严格以来select语句本身, 语句顺序、大小写不能变;②不能包含动态数据;③可以使用SQL_NO_CACHE语句使该语句不被缓存,例如select SQL_NO_CACHE * from emp where empno = 1234567;
五、分区(partition)
将某张表的数据分别存储到不同区域
1、创建分区,在创建表时,指定分区的选项
create table table_name(定义) partition by 分区算法 (参数) 分区选项
tips:利用show variables like ‘have_partitionong‘来查看是否支持分区
2、四种分区算法
取余:key,hash
条件:list,range
例如:
create table xxx(xx) partition by key (id) partitions 5;//将表按照id取余分为5个区
paritition by hash (month(date)) parititions 12;//将表从date中取出的month分为12个
paritition by list (month(date))(paritition spring values in (3,4,5), paritition summer values in (6,7,8,9), partition autumn values in (10,11), partition winter values in (12,1,2));//使用list按照具体的值划分
partition by range (year(date))(partition p_80 values less than (1990), partition p_90 values less than (2000), partition p_00 values less than maxvalue);//使用range划分范围进行分区
3、管理分区
①取余key has中
增加分区数量: add partition partitions N
减少分区数量 :coalesce partition N
②条件list range中
增加分区: add partition(pritition p_new00 values less than (2010));
删除分区: drop partition partition_name;//注意,会导致删除的分区数据丢失
4、选择分区算法
①平均分配:按照主键进行key取余分区即可
②按照某种业务逻辑分区:选择最容易筛选的字段,比如整数型
六、表合并
可以使用mrg_myisam使多个结构相同的myisam表合并到一起
七、逻辑
①并发性的sql:少用不用多表操作,如子查询,jion等;将复杂的SQL差分多次执行
②大量数据的插入:
对于myisam:建议先使用 alter table table_name disable keys 禁用索引约束,再大量数据插入完毕后,再利用 alter table table_name enable keys 开启
对于innodb:
Drop index, drop constraint 要保留主键 Begin transaction|set autocommit=0; [数据本身已经按照主键值排序] 大量的插入 Commit; Add index, add constraint
另外,insert into table_name values (),(),()...以10量级为单位即可,不宜过多
八、慢查询日志
定位执行比较慢的查询语句
show variables like ‘slow_query%‘ //查看慢查询日志状态以及位置
show variables like ‘%long_query%‘ //对快慢查询的时间临界点进行设置