1)先运行看看是否真的很慢注意設置SQL_NO_CACHE
2)where条件单表查,锁定最小返回记录表这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分別查询看哪个字段的区分度最高
3)explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
5)了解业务方使用场景
6)加索引时参照建索引的几大原则
7)观察结果不符合预期继续从1开始分析
task_struct
类型的结构体在这个结构体中存储着进程相关的一系列信息(内存指针:程序在内存中的位置,程序计数器:即将执行的指令标识符ID:进程id等…),操作系统想要操作对这个进程进行操作实际上就是对这个task_struct
结构体中嘚内容进行修改,因此进程本质上就是一个task_struct
结构体也叫PCB
进程控制块
pcb
事务被视为不鈳分割的最小单元事务的所有操作要么全部提交成功,要么全部失败回滚
回滚可以用日志来实现,日志记录着事务所执行的修改操作在回滚时反向执行这些修改操作即可。
数据库在事务执行前后都保持一致性状态
在一致性状态下,所有事务对一个数据的读取结果都昰相同的
一个事务所做的修改在最终提交以前,对其它事务是不可见的
一旦事务提交,则其所做的修改将会永远保存到数据库中即使系统发生崩溃,事务执行的结果也不能丢失
可以通过数据库备份和恢复来实现,在系统发生崩溃时使用备份的数据库进行数据恢复。
事务中的修改,即使没有提交对其它事务也是可见的。这样会提高性能但是会导致脏读問题。
一个事务只能读取已经提交的事务所做的修改换句话说,一个事务所做的修改在提交之前对其它事务是不可见的该级别可以解決脏读为问题,但不能避免不可重复读
保证在同一个事务中多次读取同样数据的结果是一样的。可以解决不可重复读的问题但还是不能避免幻读的问题。
强制事务串行执行可以解决所有问题。最高级别的隔离
MySQL默认的隔离级别是可重复读。
- 脏读数据:T1 修改一个数据T2 隨后读取这个数据。如果 T1 撤销了这次修改那么 T2 读取的数据是脏数据。
- 不可重复读:T2 读取一个数据T1 对该数据做了修改。如果 T2 再次读取这個数据此时读取的结果和第一次读取的结果不同。
- 幻读:T1 读取某个范围的数据T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据此时读取的结果和和第一次读取的结果不同。
一般可以分为两类一个是悲观锁,一个是乐观锁悲观锁一般就是我们通常说的数据库鎖机制,乐观锁一般是指用户自己实现的一种锁机制
悲观锁:它对于数据被外界修改持保守态度,认为数据随时会修改所以整个数据處理中需要将数据加锁。悲观锁一般都是依靠关系数据库提供的锁机制事实上关系数据库中的行锁,表锁不论是读写锁都是悲观锁
悲觀锁按照使用性质划分:
共享锁(Share locks简记为S锁):也称读锁,事务A对对象T加s锁其他事务也只能对T加S,多个事务可以同时读但不能有写操莋,直到A释放S锁
排它锁(Exclusivelocks简记为X锁):也称写锁,事务A对对象T加X锁以后其他事务不能对T加任何锁,只有事务A可以读写对象T直到A释放X锁
更新锁(简记为U锁):用来预定要对此对象施加X锁,它允许其他事务读但不允许再施加U锁或X锁;当被读取的对象将要被更新时,则升級为X锁主要是用来防止死锁的。
悲观锁按照作用范围划分:
乐观锁:顾名思义就是很乐观,每次自己操作数據的时候认为没有人回来修改它所以不去加锁,但是在更新的时候会去判断在此期间数据有没有被修改
所有字段:和待更新字段类似,只是使用所有字段做版本控制信息只有所有字段都没变化才会执行更新。
乐观锁几种方式的区别:
新系统设计可以使用version方式和timestamp方式需要增加字段,应用范围是整条数据不论哪个字段修改都会更新version,也就是说两个事务更新同一条记录的两个不相关字段也是互斥的,不能同步进行旧系统不能修改數据库表结构的时候使用数据字段作为版本控制信息,不需要新增字段待更新字段方式只要其他事务修改的字段和当前事务修改的字段沒有重叠就可以同步进行,并发性更高
范式理论是为了解决以上提到四种异常。
高级别范式的依赖于低级别的范式1NF 是最低级别的范式。
每个非主属性完全函数依赖于键码
非主属性不传递函数依赖于键码。
概念:根据两个表或多个表的列之间嘚关系从这些表中查询数据。分为三种:内连接、外连接、交叉连接
内连接(INNER JOIN):仅将两个表中满足连接条件的行组合起来作为结果集在內连接中,只有在两个表中匹配的行才能在结果集中出现
外连接(OUTER JOIN): 在内连接的基础上还包含表中所有不符合条件的数据行,并将相对应嘚表列填写NULL
并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁
外键:InnoDB 支持外键。
备份:InnoDB 支持在线热备份
崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢
其它特性:MyISAM 支持压缩表和空间数据索引。
Mysql常见索引类别有:主键索引、唯一索引、普通索引、全文索引、组合索引
Mysql各种索引区别:
普通索引:最基本的索引,没有任何限制
唯一索引:与"普通索引"类似不同的就是:索引列的值必须唯一,但允许有空值
主鍵索引:它 是一种特殊的唯一索引,不允许有空值
全文索引:仅可用于 MyISAM 表,针对较大的数据生成全文索引很耗时好空间。
组合索引:為了更多的提高mysql效率可建立组合索引遵循”最左前缀“原则。
最左前缀原则:顾名思义最左优先,比如我们建立了一个以(a,b,c)为组匼的索引,那么将会得到:a, ab,abc三种索引
若我们按列“b”进行查找,或者按列(bc)查找都不会使用到索引,只有以上三种索引可以使用
但为什么我们使用BTree比使用Hash多呢?主要Hash本身由于其特殊性也带来了很多限制和弊端:
2. 联合索引中,Hash索引不能利用部分索引键查询
对于联合索引中的多个列,Hash是要么全部使用要么全部不使用,并不支持BTree支持的联合索引的最优前缀也就是联合索引的前面一个或几个索引键进行查询时,Hash索引无法被利用
由于Hash索引中存放的昰经过Hash计算之后的Hash值,而且Hash值的大小关系并不一定和Hash运算前的键值完全一样所以数据库无法利用索引的数据来避免任何排序运算。
4. Hash索引任何时候都不能避免表扫描
Hash索引是将索引键通过Hash运算之后将Hash运算结果的Hash值和所对应的行指针信息存放于一个Hash表中,由于不同索引键存在楿同Hash值所以即使满足某个Hash键值的数据的记录条数,也无法从Hash索引中直接完成查询还是要通过访问表中的实际数据进行比较,并得到相應的结果
对于选择性比较低的索引键,如果创建Hash索引那么将会存在大量记录指针信息存于同一个Hash值相关联。这样要定位某一条记录时僦会非常麻烦会浪费多次表数据访问,而造成整体性能底下
Mysql数据库用过吧l里面的索引是基于什么数据结構。
答:主要是基于Hash表和B+树
数据库使用树型结构来增加查询效率并保持有序。那么为什么不使用二叉树来实现数据结构呢,二叉树算法时间复杂度是lg(N)查询速度和比较次数都是较小的。实际上查询索引操作最耗资源的不在内存中,而是磁盘IO索引是存在磁盘上的,当數据量比较大的时候索引的大小可能达到几个G。那么我们利用索引进行查询的时候,不可能把索引直接加载到内存中只能一次读取┅个磁盘页,一个磁盘页对应着一个节点一次读取操作时一个磁盘io。在二叉树查询时最坏的情况下查找的次数是树的高度,即io次数为樹的高度B-树就是比二叉树“矮胖”的树。
B-树查询的次数并不比二叉树的次数小,但是相仳起磁盘io速度内存中比较的耗时就不足为提了。所以只要树的高度足够低io次数少,就可以提升查找性能而每个节点中有多个元素,嘟只在内存中操作
而B+树是基于B-树的,增加了如下规则:
B+树对比B-树有如下好处:
两者的根本区别是表记录的排列顺序和与索引的排列顺序是否一致。
实践中,MySQL的优化主要涉及SQL语句及索引的优化、数据表结构的优化、系统配置的优化和硬件的优化四個方面如下图所示:
优化insert语句:一次插入多值;
应尽量避免在 where 子句中使用!=或<>操作符,否则将导致引擎放弃使用索引而进行全表扫描;
应盡量避免在 where 子句中对字段进行null值判断否则将导致引擎放弃使用索引而进行全表扫描;
优化嵌套查询:子查询可以被更有效率的连接(Join)替代;
很多时候用 exists 代替 in 是一个好的选择。
建议在经常作查询选择的字段、经常作表连接的字段以及经常出现在order by、group by、distinct 后面的字段中建立索引但必须注意以下几种可能会引起索引失效的情形:
以“%(表示任意0个或多个字符)”开头的LIKE语句,模糊匹配;
OR语句前后没有同时使用索引;
數据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型);
数据库表结构的优化包括选择合适数据类型、表的范式的优化、表的垂直拆分和表的水平拆分等手段
操作系统配置的优化:增加TCP支持的队列数
使用 EXPLAIN 关键字可以知道MySQL是如何处理你的SQL语句的,以便分析查詢语句或是表结构的性能瓶颈通过explain命令可以得到表的读取顺序、数据读取操作的操作类型、哪些索引可以使用、哪些索引被实际使用、表之间的引用以及每张表有多少行被优化器查询等问题。当扩展列extra出现Using filesort和Using temporay则往往表示SQL需要优化了。
主要涉及三个保证线程顺序:binlog 保证线程顺序、I/O 保证线程顺序和 SQL 保证线程顺序。
)是一项全新的数据库革命性运动,早期就有人提出发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型嘚数据存储相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入直接点解释就是:适用关系型数据库的時候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可可以考虑使用更加合适的数据存储。
若服务器使用关系型數据库当有大量数据产生时,服务器不能够满足当前的系统需求时若要提升系统处理数据的能力,只能选择两种方式一是提高性能,二是增大规模若选择提高性能,就需要买更好的服务器但往往成本较高若增大规模只能是用廉价的服务器才可以控制成本,在需要時购买更多的廉价服务器
答案是否定的!他也可以在你需要对数据进行缓存处理操作时进行使用,同时也可以對数组或集合类型的数据进行高速处理
适合处理一般量级的数据(银行转账和钱)
非关系数据库的优缺点(redis和MangDB)
为了处理海量数据,非关系数据库设计之初就是为了替代关系型数据库的关系
1.海量数据的增删改查是可以的
2.海量数据的维护和处理非常轻松
1.数据和数据没有关系他们之间就是单独存在的
2.非关系数据库没有关系,没有强大的事务关系没有保证数据的完整性和安全性
適合处理海量数据,保证效率不一定安全(统计数据,例如微博数据)
Redis是一款基于内存的且支持持久化、高性能的Key-Value NoSQL 数据库其支持豐富数据类型(string,listset,sorted sethash),常被用作缓存的解决方案Redis具有以下显著特点:
速度快,因为数据存在内存中类似于HashMap,HashMap的优势就是查找和操作嘚时间复杂度都是O(1);
支持事务操作都是原子性,所谓的原子性就是对数据的更改要么全部执行要么全部不执行;
丰富的特性:可用于緩存消息,按key设置过期时间过期后将会自动删除。
存储过程是事先经过编译并存储在数据库中的┅段SQL语句的集合进一步地说,存储过程是由一些T-SQL语句组成的代码块这些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删妀查),然后再给这个代码块取一个名字在用到这个功能的时候调用他就行了。存储过程具有以下特点:
存储过程只在创建时进行编译以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次所以使用存储过程可提高数据库执行效率;
当SQL语句有变動时,可以只修改数据库中的存储过程而不必修改代码;
减少网络传输在客户端调用一个存储过程当然比执行一串SQL传输的数据量要小;
通过存储过程能够使没有权限的用户在控制之下间接地存取数据库,从而确保数据的安全
SQL中的drop、delete、truncate都表示删除,但是三者有一些差別:
Delete用来删除表的全部或者一部分数据行执行delete之后,用户需要提交(commmit)或者回滚(rollback)来执行删除或者撤销删除 delete命令会触发这个表上所有的delete触发器;
Truncate删除表中的所有数据,这个操作不能回滚也不会触发这个表上的触发器,TRUNCATE比delete更快占用的空间更小;
Drop命令从数据库中删除表,所有嘚数据行索引和权限也会被删除,所有的DML触发器也不会被触发这个命令也不能回滚。
因此在不再需要一张表的时候,用drop;在想删除蔀分数据行时候用delete;在保留表而删除所有数据的时候用truncate。
视图是一种虚拟的表通常是有一个表或者多个表的荇或列的子集,具有和物理表相同的功能可以对视图进行增,删改,查等操作特别地,对视图的修改不影响基本表相比多表查询,它使得我们获取数据更容易
游标是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行从结果集嘚当前行检索一行或多行。可以对结果集当前行做修改一般不使用游标,但是需要逐条处理数据的时候游标显得十分重要。
在操莋mysql的时候我们知道MySQL检索操作返回一组称为结果集的行。这组返回的行都是与 SQL语句相匹配的行(零行或多行)使用简单的 SELECT语句,例如沒有办法得到第一行、下一行或前 10行,也不存在每次一行地处理所有行的简单方法(相对于成批地处理它们)有时,需要在检索出来的荇中前进或后退一行或多行这就是使用游标的原因。游标(cursor)是一个存储在MySQL服务器上的数据库查询它不是一条 SELECT语句,而是被该语句检索出来的结果集在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据游标主要用于交互式应用,其中用户需要滚动屏幕仩的数据并对数据进行浏览或做出更改。
触发器是与表相关的数据库对象在满足定义条件时触发,并执行触发器中定义的语句集匼触发器的这种特性可以协助应用在数据库端确保数据库的完整性。
我们知道mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能
什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列记录创建版本号和删除版本号,
而每一个事务在啟动的时候都有一个唯一的递增的版本号。
1、在插入操作时 : 记录的创建版本号就是事务版本号
比如我插入一条记录, 事务id 假设是1 ,那麼记录如下:也就是说创建版本号就是事务版本号。
2、在更新操作的时候采用的是先标记旧的那行记录为已删除,并且删除版本号是倳务版本号然后插入一行新的记录的方式。
比如针对上面那行记录,事务Id为2 要把name字段更新
3、删除操作的时候就把事务版本号作为删除版本号。比如
从上面的描述可以看到在查询时要符合以下两个条件的记录才能被事务查询出来:
1) 删除版本号 大于 当前事务版本号,就昰说删除操作是在当前事务启动之后做的
2) 创建版本号 小于或者等于 当前事务版本号 ,就是说记录创建是在事务中(等于的情况)或者事務启动之前
这样就保证了各个事务互不影响。从这里也可以体会到一种提高系统性能的思路就是:通过版本号来减少锁的争用。
read-uncommited由于昰读到未提交的所以不存在版本的问题
1)先运行看看是否真的很慢注意設置SQL_NO_CACHE
2)where条件单表查,锁定最小返回记录表这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分別查询看哪个字段的区分度最高
3)explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
5)了解业务方使用场景
6)加索引时参照建索引的几大原则
7)观察结果不符合预期继续从1开始分析