Mysql的查询过程
1. 客户端将查询指令(一个数据包)发送到 mysqlserver端
2. Server端首先检查缓存,如果能找到就返回结果,否则就进行下一步
3. Server端的解析器进行解析查询语句,进行预处理和优化查询,生成查询计划。
4. Server端的查询执行引擎调用api执行查询
5. Server端将查询结果返回客户端。
关系型数据库的结构的特点:
- 数据以表格的形式出现
- 每行为各种记录名称
- 每列为记录名称所对应的数据域
- 许多的行和列组成一张表单
- 若干的表单组成database
相应名词:
- 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
索引的定义(索引别称index,key,键):
- 首先,索引是一种数据结构。在关系数据库中,索引是对表中一列或多列的值进行排序的一种存储结构,它是表中一列或多列的值的集合,而且其中包含了对应表中记录的引用指针。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。
- Mysql的索引分为单列索引(全文索引,主键索引,唯一索引,普通索引)和组合索引。
单列索引:一个索引只包含一个列,一个表可以有多个单列索引。
组合索引:一个组合索引包含两个或两个以上的列。 - 如果一个索引(如:组合索引)中包含所有要查询的字段的值,那么就称之为覆盖索引,如SELECT user_name, city, age FROM user_test WHERE user_name = ‘feinik’ AND age > 25.因为要查询的字段(user_name, city, age)都包含在组合索引的索引列中,所以就使用了覆盖索引查询,查看是否使用了覆盖索引可以通过执行计划中的Extra中的值为Using index则证明使用了覆盖索引,覆盖索引可以极大的提高访问性能。
4. Mysql普遍使用B+Tree实现其索引结构
5. 在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的
MyISAm引擎中的索引:
- MyISAM引擎使用B+Tree作为索引结构,索引文件和数据文件是两个文件。叶结点的data域存放的是数据记录的地址。
MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。
因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
InnoDB索引实现:
- 也使用B+Tree作为索引结构。InnoDB的数据文件本身就是索引文件。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶结点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
- 叶结点包含了完整的数据记录。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键。
索引使用的优化:
MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。
- 索引的缺点:索引文件本身要消耗存储空间,同时索引会加重插入、删除和修改记录时的负担,另外,MySQL在运行时也要消耗资源维护索引,因此索引并不是越多越好。增大了表的文件大小(索引文件甚至可能比数据文件还大)。
- 以下情况适合创建索引:
2.1经常被查询的字段,即在where字句中出现的字段。
2.2在分组的字段,即在 GROUP BY 字句中出现的字段。
2.3存在依赖关系的字表和父表之间的联合查询,即主键和外键。
2.4设置唯一完整性约束的字段。 - 以下情况不适合创建索引:
3.1在查询中很少被使用的字段。
3.2拥有许多重复值的字段。
SQL语句优化:
- 避免在where子句中使用!=和<>,否则引擎将放弃使用索引而全盘扫描
- 很多时候用exists代替in是很好的选择
- 用where子句代替HAVING,因为having会在检索出全部的记录后才进行过滤
- In和not in 也要慎用 有可能造成全盘扫描
- 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引
- 任何地方都不要使用 select * from t
- 尽量避免大事务操作,提高系统并发能力
- 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描。
Redis缓存
- redis缓存如何添加到业务逻辑代码中?
Redis在内存中,因为数据存在内存中,类似于HashMap,HashMap的优势 就是查找和操作的时间复杂度都是O(1)
redis作为缓存的作用就是减少对数据库的访问压力,当我们访问一个数据的时候,首先我们从redis中查看是否有该数据,如果没有,则从数据库中读取,将从数据库中读取的数据存放到缓存中,下次再访问同样的数据的是,还是先判断redis中是否存在该数据,如果有,则从缓存中读取,不访问数据库了。