mysql优化一(存储+索引+sql优化)

#【存储过程】
create procedure test_proc() -- 存储过程
BEGIN
select name from t_user;

END;
call test_proc();-- 执行存储


show status like 'uptime';-- 数据库启动时间
show status like 'slow_queries';-- 显示慢查询次数
show status like  'connections';  -- 显示到mysql数据库的连接数
show variables like 'long_query_time';-- 查询慢查询时间
show VARIABLES like '%slow%'; -- 查询慢查询开启

#【慢查询】
-- 修改慢查询时间
set long_query_time=1; -- 但是重启mysql之后,long_query_time依然是my.ini中的值
select @@sql_mode ;
SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
SELECT * from dept;
/*部门表*/
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);  

#【索引】

select count(*) from emp; -- 一共16677224条数据
SELECT  * from emp where empno='100007'; -- 创建索引前 2.285s
alter table emp add primary key (empno);-- 添加索引用时34.475s
SELECT  * from emp where empno='100008'  ; -- 创建索引后 0.039s
#索引
show index from t_user;
#索引分类:主键索引、唯一索引、普通索引、组合索引、全文索引
#主键索引
create table aaa
(id int unsigned primary key auto_increment ,
name varchar(32) not null default '');

create table bbb (id int , name varchar(32) not null default '');
-- alter table 表名 add primary key (列名);
alter table articles drop primary key;

#查询索引
-- desc  表名;   不能显示索引名称
-- show index from 表名
-- show keys from 表名

show keys from t_user;
#全文索引
CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)
     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES
     ('MySQL Tutorial','DBMS stands for DataBase ...'),
     ('How To Use MySQL Well','After you went through a ...'),
     ('Optimizing MySQL','In this tutorial we will show ...'),
     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
     ('MySQL vs. YourSQL','In the following database comparison ...'),
     ('MySQL Security','When configured properly, MySQL ...');
错误用法:
select * from articles where body like '%mysql%'; -- 错误用法 索引不会生效
正确用法:
select * from articles where match(title,body) against ( 'database')

#唯一索引
create table ddd(id int primary key auto_increment , name varchar(32) unique);
#普通索引
create index 索引名 on 表 (列1,列名2);


#查询所用使用率
-- handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。
-- handler_read_rnd_next:这个值越高,说明查询低效。

show status like 'handler_read%';
#索引的代价
#占用磁盘空间
#对DML(update、delete、insert)语句的效率影响
#增删改会对索引影响,因为索引要重新整理。

#存储引擎    允许的索引类型
#myisam    btree    对事务要求不高,查询添加、批量添加
#innodb    btree      对事物要求高 , 评论、发帖、日志、帖子、订单、支付
#memory/yeap    Hash,btree

MyISAM 和 INNODB的区别

1. 事务安全(MyISAM不支持事务,INNODB支持事务)

2. 查询和添加速度(MyISAM批量插入速度快)

3. 支持全文索引(MyISAM支持全文索引,INNODB不支持全文索引)

4. 锁机制(MyISAM时表锁,innodb是行锁)

5. 外键 MyISAM 不支持外键, INNODB支持外键. (在PHP开发中,通常不设置外键,通常是在程序中保证数据的一致)

Memory 存储,比如我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory, 速度极快. (如果mysql重启的话,数据就不存在了)

#那些列上适合添加索引
#①    查询作为查询条件字段应该创建索引
#②    唯一性太差的字段不适合单独创建索引,即使频繁 #
#Select * from emp where sex=’男’
#③    频繁更新字段,也不要定义索引。
#④    不会出现在where语句的字段不要创建索引

#总结:满处一下条件的字段,才应该创建索引
#①    肯定在where条件经常使用
#②    该字段的内容不是唯一的几个值
#③    字段内容不是频繁变化

EXPLAIN select * from t_user ;

EXPLAIN select * from t_user where id like '%10291';
desc select * from t_user;

alter table 表名 add primary key (列名);
#创建一个联合索引
alter table dept add index my_ind (dname,loc); //  dname 左边的列,loc就是右边的列
#注意:
#1.对于创建的多列索引,如果不是使用第一部分,则不会创建索引。
#explain select * from dept where loc='aaa'\G
#就不会使用到索引
#2.模糊查询在like前面有百分号开头会失效。
#3. 如果条件中有or,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须建立索引, 我们建议大家尽量避免使用or 关键字
#4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。(添加时,字符串必须’’), 也就是,如果列是字符串类型,就一定要用 ‘’ 把他包括起来.
#5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

#SQL调优

#①    使用group by 分组查询是,默认分组后,还会排序,可能会降低速度,
#在group by 后面增加 order by null 就可以防止排序.
#explain select * from emp  group by deptno order by null;
#②    有些情况下,可以使用连接来替代子查询。因为使用join,MySQL不需要在内存中创建临时表。
#select * from dept, emp where dept.deptno=emp.deptno; [简单处理方式]
#select * from dept left join emp on dept.deptno=emp.deptno;  [左外连接,更ok!]
 

#③    对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
#应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
#select id from t where num is null
#最好不要给数据库留 NULL,尽可能的使用 NOT NULL 填充数据库.
#备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用 NULL。
#不要以为 NULL 不需要空间,比如:char(100) 型,在字段建立时,空间就固定了, 不管是否插入值(NULL 也包含在内),都是占用 100 个字符的空间的,如果是 varchar 这样的变长字段, null 不占用空间。
#可以在 num 上设置默认值 0,确保表中 num 列没有 null 值,然后这样查询:
#select id from t where num = 0

数据库数据备份

手动方式

cmd控制台:

在环境变量中配置mysql环境变量

mysqldump –u -账号 –密码 数据库 [表名1 表名2..]  > 文件路径

案例: mysqldump -u -root root test > d:\temp.sql

 

比如: 把temp数据库备份到 d:\temp.bak

mysqldump -u root -proot test > f:\temp.bak

如果你希望备份是,数据库的某几张表

mysqldump -u root -proot test dept > f:\temp.dept.sql

 

如何使用备份文件恢复我们的数据.

mysql控制台

source d:\temp.dept.bak

自动方式

把备份数据库的指令,写入到 bat文件, 然后通过任务管理器去定时调用 bat文件.

mytask.bat 内容是:

@echo off

F:\path\mysqlanzhuang\bin\mysqldump -u root -proot test dept > f:\temp.dept.sql

创建执行计划任务执行脚本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值