mysql优化(一)

数据库设计

什么是数据库范式

  • 为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。

数据库三大范式

第一范式:1NF是对属性的原子性约束,要求属性(列)具有原子性,不可再分解;(只要是关系型数据库都满足1NF)
第二范式:2NF是对记录的惟一性约束,表中的记录是唯一的, 就满足2NF, 通常我们设计一个主键来实现,主键不能包含业务逻辑。
第三范式:3NF是对字段冗余性的约束,它要求字段没有冗余。 没有冗余的数据库设计可以做到。

分表分库

  • 垂直拆分
    垂 直 拆 分 就 是 要 把 表 按 模 块 划 分 到 不 同 数 据 库 表 中(当 然 原 则 还 是 不 破 坏 第 三 范 式),这 种 拆 分在 大 型 网 站 的 演 变 过 程 中 是 很 常 见 的。当 一 个 网 站 还 在 很 小 的 时 候,只 有 小 量 的 人 来 开 发 和 维护,各 模 块 和 表 都 在 一 起,当 网 站 不 断 丰 富 和 壮 大 的 时 候,也 会 变 成 多 个 子 系 统 来 支 撑,这 时 就 有 按 模 块 和 功 能 把 表 划 分 出 来 的 需 求。其 实,相 对 于 垂 直 切 分 更 进 一 步 的 是 服 务 化 改 造,说 得 简 单 就是 要 把 原 来 强 耦 合 的 系 统 拆 分 成 多 个 弱 耦 合 的 服 务,通 过 服 务 间 的 调 用 来 满 足 业 务 需 求 看,因 此 表 拆 出 来 后 要 通 过 服 务 的 形 式 暴 露 出 去,而 不 是 直 接 调 用 不 同 模 块 的 表 ,淘 宝 在 架 构 不 断 演 变 过程, 最 重 要 的 一 环 就 是 服 务 化 改 造 ,把 用 户 、交 易 、店 铺、宝 贝 这 些 核 心 的 概 念 抽 取 成 独 立 的 服务, 也 非 常 有 利 于 进 行 局 部 的 优 化 和 治 理,保 障 核 心 模 块 的 稳 定 性
    垂 直 拆 分 用 于 分 布 式 场 景。
  • 水平拆分
    谈 到 垂 直 切 分 只 是 把 表 按 模 块 划 分 到 不 同 数 据 库 ,但 没 有 解决 单 表大 数 据 量 的 问 题,而 水 平 切 分 就 是 要 把 一 个 表 按 照 某 种 规 则 把 数 据 划 分 到 不 同 表 或 数据 库 里 。例 如 像 计 费 系 统,通 过 按 时 间 来 划 分 表 就 比 较 合 适,因 为 系 统 都 是 处 理 某 一 时 间 段 的 数 据。而 像S aaS应 用,通 过 按 用 户 维 度 来 划 分 数 据 比 较 合 适,因 为 用 户 与 用 户 之 间 的 隔 离 的,一 般 不 存 在 处 理 多 个 用 户 数 据 的 情 况,简 单 的 按 user_id范 围 来 水 平 切 分

通 俗 理 解 :水 平 拆 分 行,行 数 据 拆 分 到 不 同 表 中, 垂 直 拆 分 列,表 数 据 拆 分 到 不 同 表 中

SQL优化

MySQL如何优化
表的设计合理化(符合3NF)
添加适当索引(index) [四种: 普通索引、主键索引、唯一索引unique、全文索引]
SQL语句优化
分表技术(水平分割、垂直分割)
读写[写: update/delete/add]分离
存储过程 [模块化编程,可以提高速度]
对mysql配置优化 [配置最大并发数my.ini, 调整缓存大小 ]
mysql服务器硬件升级
定时的去清除不需要的数据,定时进行碎片整理(MyISAM)

show status
使用show status使用show status查看MySQL服务器状态信息
常用命令
--mysql数据库启动了多少时间
show status like 'uptime';
show stauts like 'com_select'
show stauts like 'com_insert' ...类推 update delete(显示数据库的查询,更新,添加,删除的次数)
show [session | global] status like .... 如果你不写 [session|global] 默认是session 会话,指取出当前窗口的执行,如果你想看所有(从mysql 启动到现在,则应该 global)
//显示到mysql数据库的连接数
show status like 'connections ';
//显示慢查询次数
show status like 'slow_queries';

什么是慢查询

MySQL默认10秒内没有响应SQL结果,则为慢查询
可以去修改MySQL慢查询默认时间

如何修改慢查询

--查询慢查询时间
show variables like 'long_query_time';
--修改慢查询时间
set long_query_time=1; ---但是重启mysql之后,long_query_time依然是my.ini中的值

  • 初始化测试数据
  • 创建表结构
/*部门表*/
CREATE TABLE dept( 
deptno MEDIUMINT   UNSIGNED  NOT NULL  DEFAULT 0,  /*编号*/
dname VARCHAR(20)  NOT NULL  DEFAULT "", /*名称*/
loc VARCHAR(13) NOT NULL DEFAULT "" /*地点*/
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
/*员工表*/
CREATE TABLE emp
(empno  MEDIUMINT UNSIGNED  NOT NULL  DEFAULT 0, /*编号*/
ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/
job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/
hiredate DATE NOT NULL,/*入职时间*/
sal DECIMAL(7,2)  NOT NULL,/*薪水*/
comm DECIMAL(7,2) NOT NULL,/*红利*/
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 /*部门编号*/
)ENGINE=MyISAM DEFAULT CHARSET=utf8 ;



/*薪水*/
CREATE TABLE salgrade
(
grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
losal DECIMAL(17,2)  NOT NULL,
hisal DECIMAL(17,2)  NOT NULL
)ENGINE=MyISAM DEFAULT CHARSET=utf8;

/*测试数据*/

INSERT INTO salgrade VALUES (1,700,1200);
INSERT INTO salgrade VALUES (2,1201,1400);
INSERT INTO salgrade VALUES (3,1401,2000);
INSERT INTO salgrade VALUES (4,2001,3000);
INSERT INTO salgrade VALUES (5,3001,9999);

创建函数

create function rand_string(n INT) 
returns varchar(255) #该函数会返回一个字符串
begin 
#chars_str定义一个变量 chars_str,类型是 varchar(100),默认值'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
 declare chars_str varchar(100) default
   'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
 declare return_str varchar(255) default '';
 declare i int default 0;
 while i < n do 
   set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));
   set i = i + 1;
   end while;
  return return_str;
  end 

create FUNCTION rand_num()
RETURNS int(5)
BEGIN
 DECLARE i int default 0;
 set i =floor(10+RAND()*500);
 return i;
END

创建存储过程

delimiter $$
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0; 
#set autocommit =0 把autocommit设置成0
 set autocommit = 0;  
 repeat
 set i = i + 1;
 insert into emp values ((start+i) ,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());
  until i = max_num
 end repeat;
   commit;
 end $$
执行存储过程
call insert_emp (100001,40000000);  

如何将慢查询定位到日志中

在默认情况下,我们的mysql不会记录慢查询,需要在启动mysql时候,指定记录慢查询才可以
bin\mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定](安全模式启动,数据库将操作写入日志,以备恢复)
bin\mysqld.exe –log-slow-queries=d:/abc.log [低版本mysql5.0可以在my.ini指定]
先关闭mysql,再启动, 如果启用了慢查询日志,默认把这个文件放在
my.ini 文件中记录的位置

Path to the database root

datadir=" C:/ProgramData/MySQL/MySQL Server 5.5/Data/"

posted @ 2019-10-03 01:26  Libbo-yu  阅读(192)  评论(0编辑  收藏  举报