构建高可用web站点(五)
数据库是web站点中重要的应用,放在第四篇是因为之前来不及总结的原因,在之前的文章我看到了无论是Mysql或者是nosql的一些缓存和分布式一些比较扩展性的功能。但是对于单个数据库来说,它的优化也是我们学习的重点。现在我就来简单说说我自己总结的一些东西。
关于Mysql:Mysql是web站点中应用很广泛的关系型数据库。这一块的东西也是有很多值得学习的东西,介绍的书籍也很多,比如《高性能Mysql》《Mysql性能调优和架构设计》《Mysql技术内幕:InnoDB引擎》等,数据库的知识也是一个很大的宝库,然后我说一下我比较想分享的。也是我日常的笔记,可能逻辑关系不太好,请多多见谅。
从Mysql执行一个查询开始说起:

1、客户端发送一条查询给服务器。
2、服务器先检查缓存(这个检查是通过一个对大小写敏感的哈希查找实现的。),如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段。
3、服务器端进行SQL解析,预处理,再由优化器生成对应的执行计划。
4、MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询。
5、将结果返回给客户端。
从中可以看出一些MySQL能够处理的优化类型:
(1)重新定义关联表的顺序
(2)将外链接转化成内连接
(3)使用等价转换规则
(4)优化COUNT()、MIN()、MAX() 没有任何WHERE的COUNT(*)例如MyISAM维护一个变量来存放数据表的行数。
(5)预估并转化为常数表达式
(6)覆盖索引扫描
(7)子查询优化
(8)提前终止查询
(9)列表IN()比较 MySQL将IN()列表中的数据先进行排序,然后通过二分查找的方式来确定列表的值是否满足条件
Mysql这里其实是有一个语法树,对于如何书写SQL能让解析更快,我也是半知半解,就不详细说明,等大家和我继续一起学习
当然,很多人都知道添加索引可以提高数据查询的速度。
根据InnoDB引擎。索引主要有B-Tree索引,HASH索引等。
这里主要讲一下B-Tree索引
主要的特征:就是不论表中的行存储在什么位置,都能够以相同的方法和速度进行查询。
1.索引的创建:
读取表的数据并对其进行排序,如果排序的内存需要超过设定,则排序将使用临时表空间
把排序结果存储在索引段的叶块中,在存储空间到达索引块的PCTFREE之前,该叶块同时也担负着分支块的重任。
当达到PCTFREE时,需要获得新的块用来存储索引行,同时生成一个分支块,在该分支块的头部存储着现有叶块的DBA,新的叶块中开始键值和它的DBA一起构成了分支块的一行数据
能够提高叶块中数据存储密度的方法:
在允许的情况下,尽量减少索引列的数量
尽量使用较大的数据块大小
灵活运用压缩键值的方法。在索引为非唯一索引的情况下,大部分键值都被重复存储,尤其是组合索引中
2.索引块的分割
由于所有的索引行都是按照特定顺序进行存储的,当我们向其中插入新的索引行时,就需要“掰开”两个相互连续的索引行并将新行插入到该位置上。
当中间值被插入时,由于所对应的索引块已经没有空余空间,所以需要分配一个新的索引块并将原来索引块中的行分开存储在两个索引块中。目的是为了放置索引块的连续分割。
不论插入、删除、还是修改,都需要消耗存储空间。所以,需要定期对经常使用的表上的索引执行重构操作。
事务和锁:
锁机制用于管理对共享资源的并发访问。InnoDB存储引擎也会在数据库内部其他多个地方使用锁,从而允许对多种不同资源提供并发访问。例如,操作缓冲池中的LRU列表,删除、添加、移动LRU列表中的元素,为了保证一致性,必须有锁的介入。
latch 轻量级的锁,因为其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差。在InnoDB存储引擎中,latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。
lock的对象是事务,用来锁定的是数据库中的对象(不同事务隔离级别释放的时间可能不同)
事务隔离级别:
·未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
·提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
·可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
·串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
脏读: 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。(区分):脏页:指的是缓冲池中已经被修改的页。
不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
InnoDB实现了两种标准的行级锁:
共享锁(S Lock) 允许事务读一行数据
排他锁(X Lock) 允许事务删除或更新一行数据
为了多粒度锁定。InnoDB支持意向锁(Intention Lock)
意向共享锁(IS Lock)一张表中某几行的共享锁
意向排他锁(IX Lock)
最后,讲一下我们平时怎么分析一条sql语句。除了打开例如慢查询日志等方式,还可以通过EXPLAIN来分析你的sql语句:
EXPLAIN中的列
id列 标识SELECT 所属的行
select_type列 Simple:意味查询不包括子查询和UNION。如果有复杂的部分,最外层标记为Primary。其他部分标记如下:
SUBQUERY:包含在SELECT列表中的子查询中的SELECT
DERIVED: MySQL会递归执行并将结果放到一个临时表中。
UNION:在UNION中的第二个和随后的SELECT被标记为UNION
table列:可以从这一列中从上往下观察MySQL的关联优化器为查询选择的关联顺序。
type列:依次从最差到最优:
ALL:全表扫描
index:只是MySQL扫描表时按索引次序进行。主要有点是避免了排序,如果在Extra列中看到Using index,说明MySQL正在使用覆盖索引,只扫描索引数据
range:范围扫描就是一个有限制的索引扫描,它开始于索引里的某一个点,返回匹配这个值域的行。带有Between或在WHERE子句带有>的查询,例如IN()和OR
ref:索引访问,返回所有匹配某个单个值的行。因此它是查找和扫描的混合体
eq_ref:使用这种索引查找,MySQL知道最多返回一条符合条件的记录。这种访问方法可以在MySQL中使用主键或者唯一性索引查找时看到
const,system:当MySQL能对查询的某部分进行优化并将其转换成一个常量时。举例:你通过将某一行的主键放入WHERE子句里的方式来选取此行的主键。
possible_keys列:显示查询可以使用哪些索引
key列:决定使用哪个索引来优化对该表的访问
key_len列:显示MySQL在索引里使用的字节数
ref列:显示了之前的表在key列记录的索引中查找值所用的列或常量。
rows列:读取的行数
Extra列:Using index:将使用覆盖索引
Using where: 将在存储引擎检索行后再进行过滤
Using temporary:使用临时表
构建高可用web站点(五)的更多相关文章
- 构建高可用web站点学习--前言
前言:本人对于提高web站点的访问量等的有很浓厚的兴趣,也学习了将近一年的时间,希望能总结点东西,虽然很多东西都是从书籍和资料中学习的,而不是原创,但是这是我总结的一点感悟和进行的分类吧.而且可能思路 ...
- 构建高可用web站点学习(二)
web站点的缓存学习 缓存在web应用里面十分常见,也有各种各样的缓存,从请求开始一直到代码处理的阶段都可以采取缓存.下面就逐一介绍: 一.客户端缓存(浏览器和http方面) 前端页面缓存主要遵循ht ...
- 构建高可用web站点(四)
首先我们来了解负载均衡的概念:英文名称为Load Balance,其意思就是将负载(工作任务)进行平衡.分摊到多个操作单元上进行执行,例如Web服务器.FTP服务器.企业关键应用服务器和其它关键任务服 ...
- 构建高可用web站点学习(一)
单个服务器如何处理请求 web服务器最简单的形式就是一个程序,它侦听HTTP请求,在收到一个HTTP请求之后做出回复.当然在接收请求后服务器所做的东西是我们关注的焦点.在下文中也会提及到node是如何 ...
- 构建高可用web站点学习(三)
分布式的构建 做为网站访问的生命线(数据访问),当然也可以采用分布式的方法来减轻单台服务器的访问压力.之前有讲过Memcached的分布式,但是Memcached服务器互不通信,所以我们也提过redi ...
- 基于docker+etcd+confd + haproxy构建高可用、自发现的web服务
基于docker+etcd+confd + haproxy构建高可用.自发现的web服务 2016-05-16 15:12 595人阅读 评论(0) 收藏 举报 版权声明:本文为博主原创文章,未经博主 ...
- 高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群
高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群 libnet软件包<-依赖-heartbeat(包含ldirectord插件(需要perl-MailTools的rpm包)) l ...
- Dubbo+zookeeper构建高可用分布式集群(二)-集群部署
在Dubbo+zookeeper构建高可用分布式集群(一)-单机部署中我们讲了如何单机部署.但没有将如何配置微服务.下面分别介绍单机与集群微服务如何配置注册中心. Zookeeper单机配置:方式一. ...
- linux RHCS集群 高可用web服务器
RHCS集群,高可用服务器 高可用 红帽集群套件,提供高可用性,高可靠性,负载均衡,快速的从一个节点切换到另一个节点(最多16个节点)负载均衡 通过lvs提供负载均衡,lvs将负载通过负载分配策略,将 ...
随机推荐
- 一个js变量以及其作用域的源码示例
今天遇到了一个问题,抽象出来的代码如下: var zoom=13; function setZoom(){ zoom=14; } function displayZoom(){ this.setZoo ...
- python-类和对象(属性、方法)的动态绑定
动态绑定 # coding=utf-8 ''' 当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性 ''' from types im ...
- mybatis 关联对象mapper.xml的写法
https://github.com/zfrHJ/mybaties/blob/master/mybaties/src/com/itheima/mybatits/mapper/OrdersMapperC ...
- [PWA] 3. Devtool
You can debug with chrom dev tool: 1. Use console to debug service worker: Swith to sw.js context th ...
- CreateProcess函数具体解释
CreateProcess说明:WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程执行指定的可执行文件. 函数原型:BOOL CreateProcess( ...
- Ubuntu设置环境变量的几种方法
1.Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1.1 永久的:需要修改配置文件,变量永久生效. 1.2 临时的:使用export命令声明即可,变量在关闭shell时失效 ...
- jsp页面禁用缓存
问题:为什么禁用JSP页面缓存 就是为了得到实时信息 怎样禁用JSP页面缓存 1.在JSP页面设置 <meta http-equiv="pragma" content=&qu ...
- Android更新UI的几种方式
之前做过一个Android采集心电图数据的程序,那才是真正的多线程,之前写的小程序:比如下载个文件,从socket接受大一点的数据流然后在ui上更新进度,我都感觉这就叫做多线程了,其实这啥都不算,用个 ...
- noip 2015 运输计划 (lca+二分)
/* 95 最后一个点T了 qian lv ji qiong 了 没学过树剖 听chx听xzc说的神奇的方法 Orz 首先求出每个计划的路径长度 这里写的倍增 然后二分答案 对于每个ans 统计> ...
- 【开源java游戏框架libgdx专题】-04-接口介绍及生命周期
在核心项目中包含6大与操作系统交互的接口,每个后端都实现了这6大接口. Application:运行应用程序并通知API的客户端应用程序级别的事件,提供日志记录设施和查询方法,例如,内存使用. Fil ...