1,innodb支持事务,myisam不支持事务
2,innodb支持外键,而myisam不支持。对一个支持外间的innodb转换为myisam时会失败
3,innodb不保存表的具体行数,执行 select count(*)from table时会全表扫描,而myisam用一个变量保存了整个表的行数,执行上述语句只需读出该变量的值就行,速度很快
4,innodb不支持全文检索,而myisam支持全文检索,查询效率比innodb高
5,innodb支持行级锁,myisam锁的粒度是表级
6,myisam表示保存成文件的形式,在跨平台的数据转移中,使用myisam存储会省去不少的麻烦。
==========
myisam不支持主外键
innodb支持
myisam管理的是非事务表,提供高速的存储和检索,以及全文检索
innodb支持事务,具有众多的特性,包括ACID
A:原子性
C:一致性
I:隔离性
D:永久性
创建索引可以大大提高系统的性能。
1、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
2、可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
3、可以加快表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4、在使用分组和排序,字句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
5、通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
缺点:
a、创建索引和维护索引要耗时间,这种时间随着数据和量的增加而增加。
b、索引要占用物理空间。
c、当对表中的数据进行增加、删除、修改时,索引也要动态维护,这样就降低了数据的维护速度。
Hash的查找时间复杂度是O(1),查找确实很快,无论找哪一个数,都可以一次性找到,但是有一个问题,我们平时找数据还会根据条件查找,where。。。。 大于。。。小于。。。。。 between and 。。。。还有排序。。。这时的时间复杂度就变成了O(n),相比hash二叉树更稳定,任何时间复杂度都是log(n),所以MySQL没有用hash。
==============
为什么不用二叉树?
二叉树的定义是“左小右大”,但会出现极端的情况,比如第一个数字是1,然后后面依次出现2,3,4,5,6……就会形成一个链,此种情况就是 “右倾”
================
平衡二叉树会旋转,根节点会随着数据的变化而变化。理论上讲此时比较次数和查找次数都很理想,但是有一个问题随着数据量的增多,树的高度也变大了,而查找的速度和树的高度成正相关!并且磁盘的IO次数也是和树的高度正相关的。
==================
二叉树一个节点上只能挂两个节点,B树一个节点上最多可以挂3个节点,这样做的好处是可以降低树的高度,因为中间还有一个节点。B树的节点不仅存储数据的指针还存储数据的data,但每一页的存储空间又是有限的,所以他相比B+树(B+树的非叶子节点只存储数据的指针,数据都存在叶子节点)的高度会高,会增加磁盘的io。
======================
B+树有两种数据结构,最底层叶子节点是链表,非链表节点是树形结构,B+树将所有数据都放在叶子节点,获取所有节点不再需要中序遍历(左–中--右),并且节点和节点之间还有指针相连。这样就加快了范围查找。
在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互拆要求的满足。
行级锁
是MySQL中颗粒度最细的一种锁,表示只针对当前操作的行进行加锁,行级锁大大减少了数据库操作的冲突。其加锁颗粒度最小,但加锁开销也最大。
特点:开销大,加锁慢,会出现死锁的情况,颗粒度最小,发生冲突的可能想也最低,并发度也最高
冲突少,加锁慢
(是MySQL中颗粒度最细的一种锁,表示只针对当前操作的行进行加锁,行级锁大大减少了数据库操作的冲突。其加锁颗粒度最小,但加锁开销也最大。, 特点:开销大,加锁慢,会出现死锁的情况,颗粒度最小,发生冲突的可能想也最低,并发度也最高)
表级锁
是MySQL中颗粒度最大的一种锁,表示对当前操作的整张表进行加锁,他实现简单,资源消耗也少,被大部分MySQL引擎支持
特点:开销小,加锁快,不会出现死锁,速颗粒度较大,发生冲突的概率较高,并发度最低
速度快,冲突多
(是MySQL中颗粒度最大的一种锁,表示对当前操作的整张表进行加锁,他实现简单,资源消耗也少,被大部分MySQL引擎支持, 特点:开销小,加锁快,不会出现死锁,速颗粒度较大,发生冲突的概率较高,并发度最低)
页级锁
是MySQL中介于行级锁和表级所之间的锁,是他们折中的一种锁,一次锁相邻的一组记录
特点:开锁和加锁介于表锁和行锁之间,会出现死锁,粒度也是介于行锁和表锁之间,并发度一般
介于行锁和表锁之间
(是MySQL中介于行级锁和表级所之间的锁,是他们折中的一种锁,一次锁相邻的一组记录, 特点:开锁和加锁介于表锁和行锁之间,会出现死锁,粒度也是介于行锁和表锁之间,并发度一般)
什么是优化?
合理的安排资源,调整系统参数使MySQL运行更快更节省资源
优化是多方面的,包括查询、更新、服务器等
优化原则:减少资源的瓶颈,减少资源占用、增加系统的反应速度
字段讲解
system仅有一行,这是const类型的特类,平时不会出现,这个可以忽略不计
const数据表只有一个匹配行,常用于primary key 或者unique索引查询,也可以理解为const是最优的
eq_ref可以用于使用=比较带索引的查询,它用在一个索引的所有部分被连接使用并且索引是primary key或者unique
ref查询条件既不是primary key也不是unique的情况。可用于=或者<或者>操作
ref_or_null该类型如同ref,但是添加了MySQL可以专门搜索包含null值的行。在解决子查询中经常使用该连接类型的优化
index_merge该连接类型表示使用了索引合并优化方法
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高
index_subquery该连接类型类似于unique_subquery,可以替换子查询
range只检索指定范围的行,使用一个索引来选择行
index该连接类型与all相同,通常比all快一点,因为索引文件通常比数据文件小
all进行全表扫描,性能最差
这5种情况都是很理想的索引使用情况
(system, const, eq_ref, ref, ref_or_null)
指出MySQL中能使用哪一个索引在该表中找到行,如果该列为null,说明没有使用索引,可以对该列创建索引来提高性能
key:显示MySQL实际决定使用的索引(键),如果没有选择索引,键是null。可以强制使用索引或者忽略索引
key_len:显示MySQL决定使用键的长度如果键是null,则长度是null
ref:显示使用哪一个列或者常数与key一起从表中选择行
rows:显示MySQL认为它执行查询必须检查的行数
extra:该列包含MySQL解决查询的详细信息
1、在使用Like关键字进行查询的查询语句中,如果匹配字符串的第一个字符为%时,索引不起作用。只有%不在第一个位置时索引才起作用
2、复合索引遵循最左前缀原则,即在查询条件中使用了复合索引的第一个字段,索引才会被使用,因此复合索引中的索引列的位置至关重要。
3、只要列中包含有null值都不会抱哈在索引中,复合索引中只要有一列含有null值,那么这一列对于复合索引就是无效的
4、在查询语句的查询条件中,只有OR关键字,且OR前后的两个条件中的列都是索引时,索引才会生效
概要
(1、在使用Like关键字进行查询的查询语句中,如果匹配字符串的第一个字符为%时,索引不起作用。只有%不在第一个位置时索引才起作用, 2、复合索引遵循最左前缀原则,即在查询条件中使用了复合索引的第一个字段,索引才会被使用,因此复合索引中的索引列的位置至关重要。, 3、只要列中包含有null值都不会抱哈在索引中,复合索引中只要有一列含有null值,那么这一列对于复合索引就是无效的, 4、在查询语句的查询条件中,只有OR关键字,且OR前后的两个条件中的列都是索引时,索引才会生效)
子查询时,MySQL需要创建临时表,查询完之后再删除,所以子查询的速度会受到一定影响,所以可以用连接查询join代替子查询,连接查询不需要建立临时表,其速度比子查询快。
一个好的数据库设计方案,对于数据库的性能往往起到事半功倍的效果。
需要考虑数据冗余,查询和更新的速度,字段的数据类型是否合理等多方面
对于字段很多的表,如果有些字段使用频率很低,而有些字段使用频率很高,可以将那些使用频率低的字段分离出来,形成一个新表。因为当一个表的数据量很大的时候,会由于使用低的字段存在而变的很慢。
对于需要经常联合查询的表,可以新建一张中间表。
通过中间表,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为查询对中间表的查询
设计表的时候应尽量遵循范式理论的规约,尽量减少冗余字段,让数据库设计看起来精致、优雅。但是,合理的假如冗余字段可以提高查询速度。
注意:冗余字段的值在一个表修改了,在另外一张表中也要同时修改,否则会出现数据不一致的情况
配置较大的内存
内存的io比硬盘快的多,可以增加系统的缓冲区容量,是数据在内存中停留的时间更长,以减少磁盘io
配置告诉磁盘,如SSD
合理分配磁盘IO
把磁盘io分散到多个设备上,以减少资源的竞争,提高并行操作能力
配置多核处理器
MySQL是多线程的数据库,多处理器可以提高同时执行多个线程的能力
不要在列上进行计算,这样将导致索引失效,从而进行全表扫描
尽量避免使用 != not in <>等否定操作,可以用or来连接条件
永远用小结果集驱动大结果集
永远为每张表设置一个id
当只有一条数据时使用limit 1
尽量不要在语句中使用函数
避免使用select * ,应该是用到哪个字段就写哪个字段
(不要在列上进行计算,这样将导致索引失效,从而进行全表扫描, 尽量避免使用 != not in <>等否定操作,可以用or来连接条件, 永远用小结果集驱动大结果集, 永远为每张表设置一个id, 当只有一条数据时使用limit 1, 尽量不要在语句中使用函数, 避免使用select * ,应该是用到哪个字段就写哪个字段)
MySQL的配置参数都在my.conf 或者 my.ini文件的[mysqld]组中
key_buf_size:索引缓冲区的大小。索引缓冲区是所有线程共享。增加索引缓冲区可以得到更好的处理索引,但这个值不是越大越好,他的值取决于内存大小,如果太大会导致系统频繁换页,也会降低系统的使用性能
table_cache:表示同时打开的的表的个数。这个值越大表示能同时打开的表的个数也越多,这个值也不是越大越好
sort_buf_size:表示排序缓冲区的大小,这个值越大,进行排序的速度也越快
innodb_buf_pool_size:表示innodb类型的表和索引的最大缓存,这个值越大查询的速度越快,但是太大会影响系统性能
max_connections:表示数据库的最大连接数,要注意连接会占用内存资源,过多连接会导致MySQL僵死
thread_cache_size:表示可以复用的线程数量,如果有很多新的线程,可以适当增大改参数的数值
wait_timeout:表示服务器在关闭一个连接时等待行动的秒数。默认值是28800
允许脏读,也就是可能读取到其他会话中未提交事务修改的数据–》会发生脏读、不可重复读、虚读
只能读取到已提交的数据。解决脏读,但不可重复读、虚读还有发生
在一个事务内的查询都是事务开始时刻一致的,innodb默认级别。解决了脏读、不可重复读,但是虚读仍有可能发生
完全串行化的读,每次读都要获得表级共享锁,读写相互都会阻塞,可以保证不同事务之间互斥,避免了脏读、不可重复读和幻读
脏读:
指一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这事另一个事务也访问了这个数据,然后使用了这个数据
不可重复读:
在同一个事务中,两个相同的查询返回了不同的结果(读取数据本身的对比),比如:在事务1期间内,事务2对事务1操作的数据进行了修改,由于事务2的修改,事务1前后读取的数据有可能不一样
幻读:
第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行,同时第二个事务也修改了这个表中的数据,这种修改是向表中插入一行新数据,那么第一个事务就会出现我明明修改了所有数据,为什么还有一个数据未修改,就好像幻读一样