打开二进制日志(二进制日志内容:更改数据库的操作)

在/etc/mysql/my.cnf中

将log_bin这一行的注释去掉就开启了后面的是保存的路径

下面的expire_logs_days是过多久,Mysql自动删除二进制日志

max_binlog_size为最大二进制日志大小

注意重启mysql后刚刚的修改才生效

shell>sudo service mysql stop

shell>sudo service mysql start

然后登入mysql

每次登陆后都会生成二进制日志

我的二进制日志具体为

mysql-bin.000001(这里的mysql为主机名字)

可以在MySQL里用:SHOW BINARY LOGS来查看

查看具体内容需要在shell里用:例如

mysqlbinlog /var/log/mysql/mysql-bin.0000002

来查看

删除所有日志文件(还会生成一个新的二进制日志文件):

mysql>RESET MASTER;

删除指定的日志文件:

mysql>PURGE MASTER LOGS TO 'mysql-bin.0000002';


to是到的意思所以上面那句为删除mysql-bin.0000001


还可以根据时间来部分删除

:mysql>PURGE MASTER LOGS BEFORE '20150531';


从二进制日志中恢复数据:

shell>mysqlbinlog --stopdatetime="2015-05-31 10:18:15"/var/log/mysql/mysql-bin.000002|mysql -u root -p

其中时间为那个二进制日志里的时间


暂停二进制日志:

mysql>set sql_log_bin=OFF;

恢复二进制日志:

mysql>set sql_log_bin=ON;

【执行flush logs的影响:会多生成一个新的日志文件】


所以上面的指令要在打开了二进制日志时候才能用。


开启错误日志(后缀为.err)

同样在my.cnf里让log_error的注释取消

查看错误日志所在的路径

mysql>show variables like 'log_error'

删除错误日志:

shell>mysqladmin -u root -p flush-logs

或者:

mysql>flush logs


启动通用查询日志(通用查询日志:用户对数据库的每一步操作):

同理在[mysqld]

里加:log

删除/其实是重新创建:

mysqladmin -u root -p flush-logs


启动慢查询日志(慢查询日志内容:执行时间超过long_query_time的查询或者不使用索引的查询)

启动设置慢查询日志:与前面的同

在my.cnf里添加:log-slow-queries(后面不加指定路径即使用其默认的data路径)

重新生成慢查询日志文件

shell>mysqladmin -u root -p flush-logs

mysql>flush logs

【慢查询日志与性能优化相关】



分析查询语句

1)explain [extended] select select_options

2)describe(可以简写为desc) select select_options

查看表的信息[show create table 表名]


什么时候索引没用

1)用like查询且%在开头

2)多列索引直接用第二个字段来查询,索引不起作用

例如:create index index_id_price on fruits(f_id,f_price);

explain select * from fruits where f_price=5.2;

这条select 语句中索引不起作用。

3)使用or关键字的查询语句前后不是索引列时



优化子查询:

子查询的效率不高,用连接(join)查询+索引来替代子查询


优化数据库结构

1)将字段很多的表分解成多个表:将常用的字段分离出来成为新表

2)增加中间表:适用于经常需要联合查询的表

3)合理增加冗余字段:

4)优化插入记录的速度:采用批量插入,使用load data infile 批量导入,插入时禁用索引(set改参数的值就行了),插入前禁用唯一性检查


分析表:analyze table 表名,分析期间加了只读的锁

检查表:check table 表名,检查期间加了只读的锁

优化表:optimize table 表名,优化碎片,优化期间加上只读的锁


优化服务器:

优化参数:详见show variables那里的解释,记得配置后重启mysql服务





可用?+命令来查看命令


mysql内置字符串函数

concat()连接

lcase()转成小写

ucase()转成大写

replace(str,search_str,replace_str)替换

substring(str,position,length)取子字符串

space(count)生成空格

ltrim()去左边的空格

repeat(string,count)重复count次


mysql内置数学函数

BIN()十进制转二进制

ceiling()向上取整

floor()向下取整

max()

min()

sqrt()开平方

rand()0-1内的随机值



mysql内置日期函数

curdate()

curtime()

time

week(date)返回日期为第几周

year(date)

datediff(exp1,exp2)两个日期之间差的天数


mysql预处理语句举例(用于优化)

mysql> prepare stmt1 from 'select * from t where id>?';

mysql> set @i=1;

mysql> execute stmt1 using @i;

mysql> drop prepare stmt1;



mysql的事务处理举例(innodb独有,用于优化)

mysql> set autocommit=0;

mysql> delete from t where id=11;

mysql> savepoint p1;

mysql> delete from t where id=10;

mysql> savepoint p2;

mysql> rollback to p1;(p2后面的还原点全部自动失效)

{

mysql> rollback;回滚到最原始的还原点

mysql> commit;提交

}


重排auto_increment

将auto_increment 恢复成1

1)truncate table 表名;

2)alter table 表名 auto_increment=1;






Mysql优化技巧

1)正则表达式(匹配到了就返回1否则返回0)

例如:

mysql> select "linux is very good!" regexp "^very";

会返回0


mysql> select name ,email from t where email REGEXP "@163[.,]com$"; 

但是正则表达式消耗资源


2)用rand()提取随机行

例如:随机取三条

mysql> select * from stu order by rand() limit 3;


3)group by 字句中的with rollup可以检索出更多的分组聚合信息,但是它不能喝order by 同时使用

其实好处不是很明显,个人觉得


4)group by 语句里加bit_and(位与) ,bit_or(位或)函数

例如:

mysql> select id, bit_and(kind) from t group by id;




5)mysql help的使用

? % 可以获得所以mysql>里的命令

? reg%

? contents 查看所以帮助信息



优化sql语句的一般步骤

1)看慢查询日志或者

mysql> show [session|global] status;

session(默认)表示当前连接

global表示自数据库启动至今


2)定位执行效率较低的sql语句

看慢查询日志或者

explain或者desc


查看索引的使用情况:show status like 'Handler_read%';

如果索引正在工作,Handler_read_key的值将很高,这个值代表了一行被索引值读的次数

Handler_read_rnd_next的值高则意味着查询运行低效,而且应该建立索引补救。


load infile和outfile比mysqldump导入/导出数据的效率要高一些

对于myisam表来说导入前关闭非唯一索引导入会更快

alter table t1 disable keys;

导入结束后记得打开

alter table t1 enable keys;

最好不要关闭唯一性校验

{关闭唯一性检查的语法

  set unique_checks=0;

  打开唯一性检查的语法

  set unique_checks=1;

}



对于innodb表的优化

1)导入前数据就按主键升序保存那么导入就很快了。

2)关闭事务机制




不要在网站访问高峰期使用optimize table,该语句会消耗大量CPU



优化insert语句:一次insert多个值

优化group by 语句:后面加 order by null



少用嵌套查询因为外层查询不能用索引



多用enum来固定字段,查找快


设定字符集

在my.cnf里设定


查看字符集:show character set;



不要密码登陆mysql(这个实验我没做成功)

首先关闭mysql服务

mysqld_safe --skip-grant-table --user=mysql&

mysql -uroot

就可以登录了



没有socket的时候怎么登录mysql(未做实验)

用 mysql -u root -p test --protocol tcp -hlocalhost

也能登录成功


备份数据时要加-l(加读锁,保证数据是一个完整的快照)




mysql的主从复制(未做实验)

1)先登录到mysql数据库

2)给从服务器设置授权用户

例如:

mysql> grant all slave on  *.* to user@192.168.10.2 identified by "pass";

修改主服务器的参数

主从服务器的server-id不能相同

在主服务器上获得数据一致性的快照

mysql> flush tables with read lock;

备份后记得解锁

mysql> unlock tables;



主从错误的解决(未做实验)

从数据库无法同步(show slave status)

解决方法

:mysql>slave stop;

mysql> set GLOBAL_SLAVE_SKIP_COUNTER=1;----2

mysql> slave start;


或者在从服务器上执行手动同步(改上面的第二步)

mysql> change master to

\

\

\配置和(show master status的参数同)



mysql分区

RANGE分区

示例代码:

PARTITION BY RANGE(store_id)(

  PARTITION p0 VALUESLESS THAN(6),

  PARTITION p1 VALUESLESS THAN(11),

  PARTITION p2 VALUESLESS THAN(16),

  PARTITION p3 VALUESLESS THAN(21),

);



LIST分区

例如:

PARTITION BY LIST(store_id)

(

PARTITION pnorth VALUES IN(3,5,6,7),

PARTITION peast VALUES IN(1,2,4,8),

);


HASH分区(随机的平分数据)

例如:

PARTITION BY HASH (YEAR(hired))

PARTITIONS 4;



KEY分区



分区

例如

create table t2(id int ) engine=myisam partition by hash(id) partitions 4;

可以用show create table t2来查看表的信息



INNODB表做分区:首先要设为独占表空间

要在配置里加一句:

innodb_file_per_table=1

然后做分区的语法和myisam同,创建表的时候做分区

然后插入数据。