Fork me on GitHub

mysql优化练习

mysql优化练习

二叉树做为索引

特点 : root节点 ,左节点小于root,右节点大于root

平衡二叉树,左右子树的高度不能大于1. o(logn)

根据二叉树的特点,如果删除一边节点,并在另外一边添加节点,有可能变成链表结构,复杂度变成o(n)

btree 结构

btree 根节点至少有2个子节点

m阶树的含义,每个子节点最多含有m个孩子 (m>=2)

除了根节点和叶节点外,其它节点至少有ceil(m/2)个孩子,其中ceil 取上限值 (例如1.5 取2)

所有叶子结点高度都一样。

b+ tree

++

hash索引 用于等值的查询比b+tree 效率高,但是不能范围查询。

bitmap

聚簇索引和非聚簇索引

如果表有主键,那么主键作为聚簇索引,一个表只能有一个聚簇索引,聚簇索引存储行信息,非聚簇索引存储非聚簇索引和聚簇索引,需要拿到聚簇索引之后在进行查询才能获取数据。

如果没有主键那么第一个非空的字段作为一个聚簇索引

以上都不满足,隐式的创建一个主键(聚簇索引)。

开启慢查询日志

Show variables like ‘%queries%’
查看是否启用慢查询
show variables like ‘slow_query_log’;
set global slow_query_log = on;
Set global slow_query_log_file=’’;
Set global log_queries_not_using_indexs=on;
Set global long_query_time= 1 ; 1s
可以强制走什么索引
select count(id) from tab force index(primary) ;
这句未必走主键索引,查询优化器可能会选择非聚簇的索引

use information_schema;
select table_schema, sum((data_length+index_length)/1024/1024) M from information_schema.tables
where table_schema is not null
group by table_schema ;

select table_schema, concat(truncate(sum(data_length)/1024/1024,2),’ MB’) as data_size,
concat(truncate(sum(index_length)/1024/1024,2),’MB’) as index_size
from information_schema.tables
group by TABLE_SCHEMA;

SELECT
a.,CONCAT(‘kill ‘ ,a.id,’;’)
FROM
information_schema.PROCESSLIST a
WHERE
a.STATE = ‘Waiting for table level lock’;
select a.
from information_schema.PROCESSLIST a ;
select a.* from information_schema.innodb_trx a ;

慢查询分析工具

Mysqlddumpslow -h 看看有哪些参数

mysqlddumpslow -t 10 /xxx/xx.log |more

Pt-query-digest slow-log > slow_log.report

Pt-query-digest slow-log -review \

h=127.0.0.1,D=test,p=root,P=3306 ,u=root ,t=query-view \

—create-reviewable \

—review-history t = hostname_slow

查询次数多且每次查询占用时间长的sql

io大的sql pt-query-digest 中rows examine项

未命中索引的sql rows examine 和rows send 对比大的索引用的少

使用执行计划explain 语句

type :const常数,eq_reg,ref,range,index,all 表

possible-keys

key

Key_len

Rows 表扫描的数量

using filesort 用文件排序优化

using temporary mysql需要用临时表来存结果

max 和count 函数优化,增加索引,覆盖索引

count(*) 是包含null的,count(列)不包含

索引优化

注意索引的最左匹配原则,复合索引时候,如果遇到范围查询即停止(> ,< ,between,like)

= ,in 可以乱序的,mysql会进行优化。

如何选择合适的列进行建立索引?

where从句,group by 从句,order by 从句,on从句

索引字段越小越好

离散大的列放到联合索引前边,怎么判断离散程度,用select count(distinct 列)进行判断。

分析重复冗余的索引

pt-duplicate-key-checker -uroot -p ‘’ -h ip即可。

Pt-index-usage -uroot -p mysql-slow.log

mysql事务

ACID

原子性,一致性,隔离性,持久性

mysql默认级别rr ,repeate ,能避免幻读的, 幻读sessionA,查询数据 share in model 读锁,

SessionB 插入或者删除数据,之后SessionA 更新数据,它会把新插入的数据也同时更新,产生幻读。

表象 是快照读 伪mvcc ,mysql的多版本机制。

当前读就是加锁的增删改查语句,无论是共享锁,排它锁。

快照读 是 不加锁的非阻塞读,提高并发。

RR 以及更高级别下,默认gap间隙锁,这也是避免幻读。

对主键或者唯一索引会用到gap锁吗?

​where 条件语句如果全部命中,则不会用gap锁,只会加记录锁。

gap锁会出现在非唯一索引或者不走索引的当前读中!

表结构优化

尽可能使用not null 定义字段并设置默认值,因为null值可能增加复杂度

可以使用unix_timestamp(‘2014-09-21’) 存储时间为int

使用from_unixtime(timestr)

Biting 8个字节存储ip地址 inet_aton(‘192.168.1.1’);

Net_ntoa(ipaddress)

系统配置优化

/etc/sysctl.conf

增加tcp支持的队列数

net.ipv4.tcp_max_syn_backlog=65535

Net.ipv4.tcp_max_tw_buckets=8000

Tw_reuse=1

Tw_recycle =1

Fin_timeout =10

mysql配置

innodb_buffer_pool_size

用于配置innodb的缓冲池大小,如果只有innodb表推荐占总内存的75%

innodb_buffer_pool_instances

控制缓存池的个数,默认情况下只有一个缓冲池

innodb_log_buffer_size

innodb log 缓冲的大小,由于日志最长每秒钟就会刷新所以一般不用太大

innodb_flush_log_at_trx_commit

影响innodb的io效率,一般建议为2,数据安全性高的话使用默认1. 2是把数据提交到缓冲区,也就是最多失去1s的数据。

innodb_read_io_threads

Innodb_write_io_threads

决定innodb读写的io进程数,默认为4

innodb_file_per_table

控制innodb每一个表使用独立的表空间,默认为off,设置为on

innodb_stats_on_metadata

决定mysql在什么情况下会刷新innodb表的统计信息

mycat

Pxc加上replication 二种集群方案

mysql锁

myisam 和innodb 锁类型区别?

​ 前者仅仅支持表锁,后者表锁和行锁,默认是行级锁。

​ 读锁是共享锁,写锁是排它锁。

​ 读读 不冲突,读写冲突,写读冲突,写写冲突

lock in share model 共享锁 读锁

innodb情况下,走索引的时候使用行级锁,没使用索引时候是表级锁。

mysql 5.7复制基础

mysql复制是基于binlog日志,日志有三种格式statement,row,mixed

statement 存储sql语句,存储日志量最小

row 存储event数据,存储日志量大,但是不能很直接的读取

mixed 混合。

mysql部分复制

  • master端

    binlog-do-db

    binlog-ignore-db

  • slave端

    replicate-do-db

    replicate-ignore-db

    replicate-do-table

    replicate-ignore-table

    replicate-wild-do-table

    replicate-ignore-do-table

mysql复制类型

  • 二进制日志的复制
  • 使用gtid完成基于事务的复制
  • 基于mysql5.7的 gtid 进行复制
  • GTID (Global Transaction ID)

https://www.hi-linux.com/posts/47176.html

本文欢迎转载,但是希望注明出处并给出原文链接。 如果你有任何疑问,欢迎在下方评论区留言,我会尽快答复。 如果你喜欢或者不喜欢这篇文章,欢迎你发邮件到 alonecong@126.com 告诉我你的想法,你的建议对我非常重要。

------ 本文结束感谢您的阅读! ------
0%