优化哪些方面
1.表设计上
范式,存储引擎,字段类型
2.功能上
索引,缓存,分区
3.sql语句上
合理sql,经验
4.架构上
主从复制,负载均衡,读写分离
存储引擎
存储引擎是真正存储数据的地方
Mysql 5.5
1 不支持事务
2 表级锁
3 数据和索引是分开存储
4 insert ,select 适合高速插入和检索。(bbs,博客)
5 可压缩
6 全文索引(全文搜索)full index
快 糙 猛 php mysql
压缩
INnodb
*************************** 8. row ***************************
Engine: InnoDB
- 事务处理
- 行级锁 并发性
- 按照主键排序
- 外键,维护数据完整性 (逐渐淡化)
- 考虑CPU效率和处理大数据的最佳性能
- 数据和索引一块存储
- 5.6.4开始支持全文索引
Innodb表的文件
ibdata1 这是所有的innodb表的表空间文件
开启这个选项(mysql 5.6自动开启)
mysql> show variables like \'innodb_file_per_table%\';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set (0.00 sec)
锁的概念
出现争夺资源。
读锁. 共享锁. 一个进程在读取某表的时候,另一个进程也可以读取.但是当前进程仅仅能读取这个表,而不能操作其他表.
写锁. 独占锁. 一个进程在写表时,是不允许另一个进程写,当前进程仅仅能操作这一个表.
锁的范围,精细程度上。
Myisam表是表级锁。 Innodb是行级锁。
表级锁: 开销小,加锁时间短。
行级锁:相反。
Myisam和innodb的比较
Innodb:数据完整性,并发性好。事务,且是默认表引擎
适合银行转账,等数据安全要求高的应用
- Myisam:压缩存储,适合 insert和select多的应用,博客,BBS等
- 高速并发插入,
- 压缩:
- 压缩后的数据
- 压缩后,不能再对表进行写操作
- 解压缩
除非考虑到innodb不支持的特性,否则就优先选择innodb存储引擎。
其他的存储引擎
- Archive
- 归档型。 Insert select 日志
- Memory
- 内存型.支持insert,update,delete,select.数据不能过大。
- merge
- 合并多个相同结构的myisam表。
- 应用于 项目中的水平拆分。单表记录过大。
索引
索引也是一种结构。从数据记录里提取出关键字,可以是某列,某些列,或者是列的一部分。关键字和数据记录仍然保持原来的关联关系。
删除索引
alter table mycom drop index comnum
去除索引的情况
索引的种类
索引 某列,某些列,某列的部分。
- Primary 主键索引 不重复,不为空,不能为0
- Key 普通索引 没什么要求
- Unique 唯一索引 不重复,可以为null,
- Fulltext 全文索引 列是 varchar,char,text.没什么要求。 关键字来自列的部分
共同点:都是从数据记录里提取出的关键字。都为了查询提速。
差异性:就是关键字的要求不同。
复合索引。 关键字来源于多个列。
前缀索引。 关键字来自于某列的前N个字符。
索引的使用
@ SQL执行计划 explain
使用索引时的情况。
explain select * from mycom where con=12345656
没有使用索引时的结果
Mysql 5.5之前,explain只能针对select,现在insert ,update,delete都可以。
@ 检索数据时使用 where
Where 字段名=字段值,
加索引的列,数值分布比较广泛。Where sex=’1’分布不广泛。
索引是占据硬盘空间。影响写数据的速度。
@ 排序时也可以使用 order by
排序字段comname加上了索引后
Using filesort 排序 。外部排序(硬盘上,mysql使用order by ). (内部排序,冒泡排序是一个例子)
@索引覆盖
查询时索引覆盖了数据。
查询的数据,直接在索引中就有,而索引在内存中,查询时候不需要去数据区中检索,直接在索引中就可以查到。
使用索引需要注意的地方
列独立
左原则
复合索引中,查询时只要用到了最左边的列,就能应用上索引。
Like ‘abc%’,’abcd_%’ 只要以确定的字符开始的,也可以使用索引。
Order by
Or
Or两端的字段,必须都建立索引,才有可能使用。
列类型是字符串,字符常量没有使用引号
Name Varchar,char(),’abcdef’,’123456’
Select * from user where name=’123456’ //name字段建立索引,就会使用。
Select * from user where name=123456 //有可能不使用索引
存在索引,使用也正确,但是不使用
Select * from user where col>1 and <90 (均匀分布时)
Select * from mycom where comnum > 12990
Mysql智能化的选择结果。
Mysql觉得 在索引和数据之间来回切换,造成的开销比实际使用索引要大,放弃使用索引。
全文索引
解决like
Like ‘%美食%’;
Field regexp ‘’;
全表扫描。
Fulltext
使用全文索引的方式查询
全文索引默认不支持中文,因为:
- 英文天然以空格为区分,分割符。中文没有。
- 中文分词。有一套关键字词库。
- Sphinx,可以作为mysql插件来使用。只支持俄文和英文,Coreseek中文包。
- lucence
- 核心功能:建立全文索引,中文分词。
前缀索引
关键字的提取,是某个列的前N个字符
前N个字符,所达到的辨识度无限接近于使用整个字段达到的辨识度。
Create Index 索引名 on 表名 (field(N))
N到底是多少?
经过测试 N=9
Create index preindex on mycom (pass(9))
索引覆盖。应用不了前缀索引。
其他优化的地方
只查询相关的列
Select id,name,
一旦涉及到数据库迁移,或者表结构修改等情况下,会造成大面积的修改代码。
慎用select *
节省带宽的功能。
分解复杂查询
禁用子查询,join.。这些操作涉及锁。影响并发。
不宜建立索引的列
优化group by
使用order by null 避免group by 时默认的排序
优化insert
Insert into test values(1,2),(3,4) 多个value的情况
分区
适合数据量1亿条以上的表。
Mysql 5.1
Show variables like ‘%partition%’
Show plugins;
*************************** 42. row ***************************
Name: partition
Status: ACTIVE
Type: STORAGE ENGINE
Library: NULL
License: GPL
Partition
分区语法
Create table
Key(),hash(),list(),range()
查询缓存
mysql> show variables like \'%query_cache%\';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 1048576 |
| query_cache_type | OFF | //是否开启查询缓存
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
6 rows in set (0.00 sec)
需要在配置文件设置 query_cache_type=On|1
慢查询日志
可以为当前进程开启。
慢查询日志,不是优化措施,它可以帮助我们找到那些查询超过某个时间点的SQl语句。