数据库性能调优

数据库调优,就好比盖楼打地基,地基打得不稳,楼层一高,就会塌方。数据库也是如此,数据少,并发小,隐藏的问题是发现不了的,只要达到一定规模后,所有的问题就会全部曝露出来了,所以前期的设计阶段尤为重要。

数据库优化分类

  • 硬件
  • 网络
  • 软件

硬件、网络取决于公司的经济实力。

软件再分为表设计(字段类型、存储引擎)、SQl语句与索引、配置文件参数、体系架构等方面的优化。

表设计优化

一个好的数据库设计对于数据库的性能优化常常会起到事半功倍的效果。合理的数据库结构不仅可以使数据库占用更小的磁盘空间,而且能够使查询速度更快。

表优化的常用方法

  • 将字段很多的表分解成多个表

    对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大的时候,会由于使用频率低的字段的存在而变慢。

  • 增加冗余字段

设计数据库表时应尽量遵守范式理论的约定,尽可能减少冗余字段。但是合理地加入冗余字段也可以提高查询速度。这就是以空间换时间。

总结:在开发应用程序时,设计的数据库要最大程度地遵守三范式。但是,三范式最大的问题在于通常需要join很多表,而这个会导致查询效率很低。所以有时候基于性能考虑,我们需要有意违反三范式,适度的冗余,以达到提高查询效率的目的。

字段类型的选取

原则:选择字段的一般原则是保小不保大,能用占用字节少的字段就不用大字段。

采用合适的锁机制

  • MySQL的锁有以下几种形式:
    • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率高,并发度最低。MyISAM属于这种类型。
    • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率小,并发度最高。InnoDB就是行锁。

表锁特点

MyISAM存储引擎只支持表锁,所以对MyISAM表进行操作,会存在以下情况:

  • 对MyISAM表的读操作,不会阻塞其他进程对同一个表的读请求,但会阻塞对同一个表写请求。只有当读锁释放后,才会执行其他进程的写操作。
  • 对MyISAM表的写操作,会阻塞其他进程对同一个表的读和写操作,只有当写锁释放后,才会执行其他进程的读写操作。
表锁特点实验
读锁阻塞写锁
  • 准备一个千万级的数据表

    create table t2(id int primary key auto_increment, name varchar(20))engine=myisam;

    insert into t2(name) values(‘a’),(‘b’),(‘c’);

    insert into t2(name) select name from t2;//这条语句重复n次后就有很多数据

  • 当正在读myisam,同时不能写

    select * from t2;

update t2 set name= ‘liangzhi’ where id = 1;

更新语句,只有等查询语句执行结束后才可以执行,也就是说读锁释放后,才能进行写操作。否则一直在等待状态。

写锁阻塞读/写锁

update t2 set name=’gz’ where id > 1000;

这个时候,t2已经加了写锁,这个时候,去执行查询。也是只能等待写锁释放。

select * from t2 limit 1;

行锁的特点

InnoDB存储引擎是通过索引上的索引项加锁来实现的,这就意味着:只有通过索引条件检索数据,InnoDB才会使用行级锁。否则,InnoDB将使用表锁。

行锁使用情况

实验(验证行锁只会影响到对应行,而不是整个表)
create table t3(id int primary key auto_increment,name varchar(20))engine=innodb;

insert into t3(name) values('a'),('b'),('c');

insert into t3(name) select name from t2;//这条语句重复n次后就有很多数据

update t3 set name='gz' where id > 1000;//影响的是id>1000的行
    
select * from t3 limit 1;

InnoDB引擎与MyISAM引擎对比

  • 事务支持

    MyISAM是非事务安全型的,而InnoDB是事务安全型的,也就是支持事务

  • 锁机制

    MyISAM锁是表锁,锁开销最小,而InnoDB支持行锁,锁管理开销大,支持更好的并发写操作。

  • 文件保存形式

    每张MyISAM表存放在3个文件中:frm文件存放表格存放,数据文件是MYD,索引文件是MYI

  • 数据安全性 InnoDB表比MyISAM表更安全,因为InnoDB具有崩溃恢复能力。

如何选择表引擎

InnoDB支持行锁、事务。如果应用中需要执行大量的读写操作,应该选择InnoDB,这样可以提高多用户并发操作的性能。在MySQL5.5之后版本,Oracle已经很少支持MyISAM了,所以建议优先选择InnoDB引擎。

SQL优化与合理利用索引

系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和高效SQL语句之间的速度差别可以达到上百倍。

如何定位执行很慢的SQL语句

开启慢查询日志的好处是可以通过记录、分析慢SQL语句来优化SQL语句

开启慢查询日志,在my.cnf配置文件中,加入以下参数:

slow_query_log = 1 slow_query_log_file = mysql.slow long_query_time = 1 # 超过2秒的SQL会记录下来

SQL语句优化建议

  • 避免使用子查询,可以用left join表连接替换
  • limit分页优化

    传统的分页:select SQL_NO_CACHE * from t2 order by id limit 99999,10;

    传统的的分页,虽然用上了id索引,但要从第一行开始起定位到99999行,然后再扫描出后10行,相当于进行一个全表扫描,显然效率不高。

    优化方法:

    select SQL_NO_CACHE * from t2 where id >= 100000 order by id limit 10;

    优化方法利用id索引直接定位100000行,然后再扫描出后10行。速度相当快。

  • 避免使用*号,只查需要的字段
  • 多使用limit,减少数据传输
  • 可以使用冗余来减少关联表查询
  • 给常在where条件后的字段天剑索引,并且合理使用索引

合理使用索引

适当的索引对应用的性能来说相当重要,而且也建议在MySQL中使用索引,它的速度是很快的。

但是索引也是有成本的。每次向表中写入时,如果带有一个或多个索引,那么MySQL也要更新各个索引。索引还增加了数据库的规模,也就是说索引也是占据空间的。

只有当某列被用于where子句时,才能享受索引性能提升的好处。如果不使用索引,它就没有价值,而且会带来维护上的开销。

索引常见用法

  • 依据where查询条件建立索引

    select a,b from tab a where c = ? //应该给c建立索引

  • 使用联合索引,而不是多个单列索引

    select * from tab where a = ? and b =? //给(a,b)建立联合索引,而不是分别给a,b建立索引

  • 联合索引中索引字段的顺序根据区分度排,区分度大的放在前面

    //(name,sex);//将name放前面,因为name的区分度更大。因为sex只有0 1 2 这个三个值。

  • 合理创建联合索引,避免冗余

    //(a),(a,b),(a,b,c)只要给(a,b,c)建立索引就行

  • order by 、group by 、 distrinct字段添加索引

用不到索引的情况

  • 字段使用函数,将不能用到索引

    select createtime from aa where date(createtime) = curdate();

    //where后面的字段(createtime)使用函数,将不会使用到索引。

  • 用数字当字符类型,数字一定要加引号

    select * from user where name = 123 //这SQL语句用不到name索引

    select * from user where name = ‘123’ //这样写才会用到name字段上的索引

  • 在使用like关键字进行查询的语句中,如果匹配字符串的第一个字符为”%”,索引不会起作用。

  • 联合索引,只有查询条件中使用了这些字段中第一个字段时,索引才会被使用

    create index in_name on user(name,email) explain select * from user where name = ‘jack’; //用到索引 explain select * from user where email = ‘jack@qq.com’; //用不到索引

  • 使用OR关键字的查询语句

    • 查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,查询中才使用索引。否则查询将不使用索引。
主从数据库

读写分离

主数据库负责写,从库负责读 从库复制主库bin-log日志

如何查看bin-log

使用mysql提供命令 mysqlbinlog 查看bin-log内容

bin-log的作用

  1. 可以做数据恢复 数据库经常做备份。

  2. 可以做读写分离

主从配置

优点:1. 减轻数据库压力 2. 提高查询速度
3. 从库可以备份数据

缺点:1. 数据同步可能存在时间差。

对策:数据实时性要求高的场合,数据还是从主库查询。

建议开启从库的bin-log,原因:1. bin-log可以做备份

  1. 万一主库挂掉,从库可以迅速转换成主库。

重点

1. 会话控制 
    a. 为什么需要会话控制
    b. SESSION与COOKIE的区别与联系
    c. 如果禁用COOKIE,SESSION是否还可以使用,怎么识别用户?

2. 各种区别
    a. post与get区别
        从协议角度看,post与get区别在于,get一般用来获取
        服务器的数据,post一般用于向服务器发送数据。

        从具体应用(表单):
            1. 大小
            2. 安全性
            3. 

    c. include require区别  include_once

    d. echo ,print ,print_r 区别
        echo,print是语言结构,print_r是函数

3. 数据库优化(*****)


4. 数据库基本操作(****)

5. 能够写出一些简单的正则
    匹配到a连接中的href里面的内容
    <link rel="stylesheet" type="text/css" href="fdsjakf">
    <a href="fdsajfk">fdsjak</a>

6. 面向对象一些概念

7. javascript

8. 你会哪些版本控制器
    svn  git

视频学习网址:

模拟环境学习网址:

资源网站:

前端框架网站:

上传插件:

程序员面试题:

翻墙软件推荐:

弹窗对话框插件:

图片裁剪插件:

基于bootstrap后台框架:

蘑菇街开源的一款企业办公及时通信软件:

使用PHP+Swoole实现的网页即时聊天工具

PHP聊天框架:

常用IDE(集成开发环境):

  • phpstorm
  • webstorm
  • Zend Studio

收集了有关互联网相关信息(RFC)

笔记02

水平分表

优点:减少单表记录行数,加快查询速度

缺点:增加了代码维护难度( 代码需要修改 )

分区技术

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)

PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN (21)
);




select id from employees where store_id = 4;//p0
从小的文件中搜索内容要比大文件要快

//partition by range (范围)



MYI  以.myi是存放索引
MYD  以.myd存放数据

FRM   存放表定义、表结构

只要一个表有三个文件,这个表的引擎一定是myisam

主从、分表、分区技术

CDN( 内容分发网络 )

通过在网络各处(网络节点)放置服务器,将静态资源缓存在离用户最近的地方,使用户以最快速度获取数据。


CDN放置的是静态资源:CSS、JS、图片、视频、字体





服务器在北京   但是在广州有CDN服务器。在上海也有CDn

广州用户要数据( 数据库数据、网页数据、样式 )

上海用户要数据( 静态数据去上海 )

就近原则。

CDN : 使用第三方提供。 百度、阿里、七牛

反向代理服务器

反向代理就是一个缓存。



如果反向代理服务器有用户要的数据,那么直接由反向代理服务器直接返回给用户。不需要再访问我们服务器集群。


如果反向代理服务器没有用户要的数据,那么就由反向代理服务器
代理我们用户去访问我们服务器集群。拿到数据,先在反向代理服务器
保存一份,然后再给到用户。


反向代理服务器:Nginx  /   Squid  

文件服务器

TFS (淘宝文件系统)  分布式的文件系统,

但是TFS比较适用于类似淘宝商城。( 小文件比较多的情况 )


GFS(谷歌文件系统)

站内搜索

站内搜索大型网站一定不能使用。因为like会导致一个全表扫描。

就是一个表如果有1000万行数据,那么like就扫描1000万数据。



站内搜索使用:sphinx(斯芬克司)、但是sphinx不支持中文。

coreseek、xunsearch(建议使用这个。因为这是国产,中文文档多 )

建议:研究xunsearch,然后把它用到你的项目中。

不能现在就停。

NoSQL( 非关系型数据库 )

与mysql不同点:NoSQL的数据存放内存里面去。

NoSQL产品: Redis /  MongoDb  / Hbase

百度:产品:搜索、地图、百科、贴吧

    搜索有专门的服务器集群
    地图有服务器
    贴吧服务器

    这样做的好处: 1、 容易维护  2、 提高系统速度

经营自己的项目

好处:可以用自己的感兴趣的所有技术。

谷歌技术。每年有一些分享会议。

谷歌 IO大会。 谷歌还会公布他一些技术。

IDE(集成开发环境)

PHP: phpstorm zendStudio

消息队列(让你的请求在排队)

队列:先进先出。

函数:array_push() 尾部进去  array_pop()  头部出来

总结:

1. 架构:  CDN、 反向代理服务器( Nginx/Squid )

负载均衡器( LVS/F5 ) =》  应用服务器

数据库( 读写分离、分布式数据库 )   非关系型数据库(  Redis MongoDb)

缓存( Memcache  File )    搜索引擎( sphinx  xunsearch )

消息队列    文件服务器( TFS /  GFS )  

=================

数据库读写分离

原理:从库复制主数据库的bin-log日志。然后 到从库执行。

主库:88 从库:168

168到88上面拿东西bin-log。

主库(88)给从库(168)授权

查看bin-log日志

bin-log作用:1、使用bin-log作数据恢复 2、利用bin-log作主从配置

利用bin-log做数据恢复

user
id  name
1    jack
2    mary

晚上00:00  做了一个备份  mysql.sql


晚上01:00  有一个新用户注册了  rose


user
id  name
1    jack
2    mary
3    rose


早上8:00时候数据库被攻击,导致数据丢失



数据恢复:mysql.sql  没有rose  

如何完整?

主从数据库优点

  1. 读写分离,减轻单个数据库压力
  2. 提高查询速度。
  3. 从库起到一个备份的作用。 提高系统可靠性、稳定性。

缺点: 1. 当并发量大的时候,实时性不高。

例子:微博。微博特点:实时性要求很高。

建议:一些实时性要求比较高的数据,还是从主库中读取。

微博? =》 主从只是一种方式。还有其他主从方式

主从配置还可以优化。

一个网站如何加快响应速度

部分:服务器(买更好的服务器)、数据库(mysql)、系统(Linux)、代码( 前端、后端 )

  1. 优化前端 a. 减少http请求 比如:减少图片、压缩css、压缩js 使用浏览器缓存

    b. CDN加速 就近原则。

    c. CSS放在页面最上面,JavaScript放在页面最下面

    d. 减少COOKIE传输

    COOKIE数据很大。不要往COOKIE里写过多的数据

  2. 后端 ( 没有人想要优化后端代码 )

  3. MySQL优化 a. 配置优化 mysql本身也有缓存(查询相同数据,第二次就是从mysql的缓存中拿的)

    b. 表结构优化 字段类型 表的设计最好符合三范式 表引擎的选择(myisam innodb) 表的字符集(gbk utf8)

    c. SQL语句 避免子查询

    减少多表联查

    d. 合理使用索引

    索引:索引其实就是一本书的目录

    有什么索引:主键、唯一、普通索引、全文索引

    索引优点:加快查询速度

    缺点:1、占用空间 2、写操作比较慢( 需要写入数据、还需要更新索引 )

    c. 分表、分区、主从数据库

  4. 缓存 Memcache Redis 页面静态化