打开二进制日志(二进制日志内容:更改数据库的操作)
在/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 [email protected] 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同,创建表的时候做分区
然后插入数据。