深入浅出mysql 笔记_《深入浅出MySQL》笔记

MySQL元数据:

-- 查看可用的字符编码

SHOW character set; | DESC infomation_schema.character_sets;

-- 查看字符集校对规则

SHOW COLLATION LIKE 'gbk'; | DESC infomation_schema.COLLATIONS;

-- 查看当前服务器|数据库的字符集和校对规则

SHOW variables LIKE 'character_set_server'; character_set_database

SHOW variables LIKE 'collation_server'; collation_database

-- 查看表的字符集和校对规则

SHOW CREATE TABLE test_tab;

-- 查看数据库模式

SELECT @@sql_mode;

-- 修改数据库模式

SET SESSION | GLOBAL sql_mode='STRICT_TRANS_TABLES';

-- 查看是否支持分区

SHOW VARIABLES LIKE 'partition';

分区4种类型:

- RANGE:适用于 1.需删除过期数据 2.经常查询包含分区键

- LIST:类似RANGE,枚举值列表分区

- HASH:平均分布 1.常规HASH(取模) 2.线性HASH(线性2的幂运算),只支持整型

- KEY:类似HASH,但不允许使用表达式,除整形外,支持其他类型

- COLUMNS:1. RANGE COLUMNS, 2. LIST COLUMNS

SQL优化

-- 查看当前session所有统计参数

SHOW status LIKE 'com_%' | Connections Uptime Slow_queries

观察以下参数:

- Com_select - Com_insert - Com_update - Com_delete

- Innodb_rows_read - Innodb_rows_inserted - Innodb_rows_updated - Innodb_rows_deleted

- Com_commit - Com_rollback

- Connnections:链接服务器次数 - Uptime:服务器工作时间 - Slow_queries:慢查询次数

1、分析SQL语句

EXPLAN [extended] sql....

ALL > index > range > ref > eq_ref > const,system > NULL

全表 索引全表 范围 唯一/非唯一索引 唯一索引 主键 / 唯一索引 常量

2、SHOW PROFILE 分析 SQL

-- 查看是否支持profile

SELECT @@have_profiling;

-- 开启session级别的profiling

SELECT @@profiling;

SET profilling=1;

-- 执行SQL

SELECT COUNT(*) FROM test;

SHOW profiles;

SHOW profile FOR query id;

关注executing, sending data, end 三项

SHOW profile cpu FOR query id; -- 查看CPU耗费时间

3、索引优化

B-Tree不是二叉树(binary),而平衡树(balanced)

能用到索引场景:

1.所有字段都匹配全值(=)

2.范围匹配

3.最左前缀匹配

4.仅对索引列查询

5.匹配列前缀,使用第一列索引

6.部分精确,部分范围

7.IS NULL会用到索引

8.ICP特性,条件过滤下放到存储引擎

不能使用索引的场景:

1.%开头LIKE查询,一般先条件缩小范围,再回表LIKE

2.数据类型出现隐式转换,例如字段是字符串,where=整数

3.复合索引不遵循最左前缀

4.Mysql认为扫索引比扫全表慢

5.多个OR,其中字段有的有索引,有的没有

4、查看索引使用情况

SHOW status LIKE 'Handler_read%';

Handler_read_key越高证明使用索引越多;

Handler_read_rnd_next越高,证明全表扫描的多;

表优化

- 1.定期分析和检查表

ANALYZE TABLE test;

CHECK TABLE test;

- 2.定期优化表

OPTIMIZE TABLE test;

常用优化

1. 大批量插入数据

- MyISAM:

ALTER TABLE test DISABLE KEYS;

LOAD DATA INFILE 'data.txt' INTO TABLE test;

ALTER TABLE test ENABLE KEYS;

- InnoDB:

1.按主键顺序保存后导入

2.SET UNIQUE_CHECKS=0关闭唯一检查

3.SET AUTOCOMMIT=0

2. 优化INSERT

1.使用INSERT INTO test VALUES(1,2),(1,3) ...

2.使用INSERT DELAYED,马上直接,不保留在内存队列

3.建表时索引文件和数据文件分开存放

4.批量插入,增大bulk_insert_buffer_size(只对MyISAM有效)

5.使用LOAD DATA INFILE

3. 优化ORDER BY

1.适当增大sort_buffer_size和max_length_for_sort_data值

2.SELECT需要的字段,尽量不要SELECT *

4. 优化GROUP BY

1.强制不排序 ORDER BY NULL

2.JOIN取代嵌套子查询

5. 优化OR

OR的各个字段都要有索引

6. 优化分页查询

1.使用关联查询,先ORDER BY且LIMIT后的分页数据,主键JOIN回表

2.记录last_page_record,利用LIMIT n查询(只用于排序字段不会重复场景)

7. 人为优化

1.SELECT COUNT(*) FROM test USER INDEX(idx_test_id);(希望参考使用索引)

2.SELECT COUNT(1) FROM test IGNORE INDEX(idx_test_id);(忽略索引)

3.SELECT COUNT(1) FROM test FORCE INDEX(idx_test_id);(强制使用索引)

8. 表分析

SELECT * FROM tab PROCEDURE ANALYSE();

SELECT * FROM tab PROCEDURE ANALYSE(16, 256);

MyISAM:

-- 查看表锁争夺情况

SHOW status LIKE 'table%';

concurrent_insert:

0:不允许并发插入

1:如果没有空洞,可以在表尾插入

2:无论是否有空,都允许插入

锁调度:

low-priority-updates:默认以读优先

SET LOW_PRIORITY_UPDATES=1:使当前连接更新请求优先级降低

指定INSERT,UPDATE,DELETE语句的LOW_PRIORITY属性,降低优先级

max_write_lock_count设置值,读大于此值,降低写优先级

InnoDB:

事物ACID属性

事物带来的问题:

更新丢失、脏读、不可重复读、幻读

隔离级别:

未提交读、已提交读、可重复读、可序列化

-- 查看行锁争夺情况

SHOW status LIKE 'innodb_row_lock';

行锁实现方式:

Record lock:对索引项加锁

Gap lock:对索引项之间的间隙枷锁

Next-key lock:前两种组合

1.如果检索记录没有索引,相当于表锁

2.不是同一行记录,但是相同索引键,也会出现行锁

3.有多个索引,不同事物使用不同索引锁定不同行

4.检索数据MySQL通过执行计划代价决定

死锁:

1.多个session并发存取多个表,约定相同顺序访问,否则有可能产生死锁

2.批量处理数据,事先对数据排序,每个线程按固定顺序处理,可降低死锁几率

3.如果更新数据,应直接申请足够级别锁,不应先申请共享锁,再申请排它锁

4.在可重复读隔离级别下,如果2个线程对相同记录加排他锁,此记录不存在,

2线程都会加锁成功,如2个线程程序都试图插入新纪录,会出现死锁,

将隔离级别改为读已提交级别可以避免

5.隔离级别为读已提交,如果2个线程对相同记录加排他锁,此记录不存在,

2线程都会加锁成功,如2个线程程序都试图插入新纪录,此时只有1个线程

能插入成功,另一个线程出现锁等待,第1线程提交后,第2线程因主键重复出错,

虽然出错,但已获得排他锁,此时有第3个线程来申请排他锁,也会出现死锁

MySQL Server优化

组成:1个主线程,4组IO线程,1个锁线程,1个错误监控线程,purge线程

内存优化原则:

适当增大内存给MySQL

如果是MyISAM表,预留适当内存给操作系统

排序区、链接区是会话级别的,根据最大连接数合理分配

MyISAM优化:

1.增大key_buffer_size,建议为内存的1/4

2.使用多个索引缓存

key_buffer_size=4G

hot_cache.key_buffer_size=2G

cold_cache.key_buffer_size=1G

init_file=/path/to/data-directory/mysql_init.sql

cache index sales in hot_cache;

cache index sales2 in cold_cache;

load index into cache sales, sales2;

3.调整中点插入策略

set global key_cache_divson_limit=70

set global hot_cache.key_cache_divsion_limit=70

4.调整read_buffer_size和read_rnd_buffer_size

以上2个参数是每个session独占

InnoDB优化:

1.增大innodb_buffer_pool_size

2.调整old sublist大小,SHOW GLOBAL VARIABLES LIKE '%innodb_old_blocks_pct%'

3.调整innodb_old_blocks_time

4.减少缓存池数量,减少内部争用,调整innodb_buffer_pool_instances

5.控制innodb buffer刷新,innodb_max_dirty_pages_pct,innodb_io_capacity

6.打开doublewrite,SHOW GLOBAL VARIABLES LIKE '%doublewrite%'

并发优化:

1.调整max_connections

2.调整back_log

3.调整table_open_cache

4.调整thread_cache_size

5.调整innodb_lock_wait_timeout

备份与恢复

备份:

mysqldump [options] db_name [tables] > out.sql

常用参数:

--add-drop-database:加上drop database语句

--add-drop-table:加上drop table语句

--no-create-db:不要create database语句

--no-create-info:不要create table语句

--no-data:不要数据,只要表结构

恢复:

mysql -uroot -p db_name < out.sql

mysqlbinlog binlog-file | mysql -u root -p

表的导出:

SELECT * FROM table INTO OUTFILE '/tmp/tmp.txt'

mysqldump -u username -T target_dir db_name table_name [option]

表的导入:

LOAD DATA INFILE 'filename' INTO TABLE table_name [option]

mysqlimport -u root -p db_name out.sql [option]

权限

授权:

GRAN SELECT ON *.* TO t1@localhost IDENTIFIED BY '123'

查看权限:

SHOW GRANTS FOR t1@localhost;

回收/更改权限:

REVOKE SELECT ON *.* FROM t1@localhost;

修改密码:

- mysqladmin -u user_name -h host_name password 'newpwd'

- SET PASSWORD FOR 't1'%'%' = PASSWORD('123')

- SET PASSWORD = PASSWORD('123')

- GRANT USERAGE ON *.* TO 't1'@'%' IDENTIFIED BY '123';

- UPDATE user SET Password = PASSWORD('123') WHERE Host='%' AND User='t1';

- GRANT USER ON *.* TO 't1'@'%' IDENTIFIED BY PASSWORD '123AE809808FDSFSFS';

删除账号:

SHOW GRANTS FOR t1@localhost;

DROP user t1@localhost;

如果此文章能给您带来小小的工作效率提升,不妨小额赞助我一下,以鼓励我写出更好的文章!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值