mysql(不断完善中)

目录

 

 1:体系结构和常用的存储引擎的优劣:

myisam

Innodb

csv

Archive

Memory

federated

 

2:为字段设置合适的类型

整数类型:

实数类型:

如何选择varchar和char类型:

存储日期数据:

3:经验索引,sql优化

对于慢sql通过查看执行计划来进行优化


 1:体系结构和常用的存储引擎的优劣:

myisam

  • 特性
  1. 他是表级锁,插入新数据时候会进行锁表,查询操作时候会加入共享锁,所以他的查询和新增是互斥的一个操作,并发的话。
  2. 它支持任何方式的损坏修复操作,但是不是事物它不支持事物 (check table tablename,repair table tablename)。
  3. 5.5版本之前原生支持全文索引,还对大字段类型的前500字符建立索引,全文索引不能优化like '%%'这种检索,他是通过分词来查询数据的。
  4. 可以进行数据压缩(myisampack命令),减少磁盘io占用,但是压缩后无法对数据进行新增更新操作。 
  • 使用场景
  1. 非事务型应用
  2. 只读类应用
  3. 空间类应用

Innodb

默认,免费的热部署备份数据方案,5.6版本的都支持全文索引和空间类函数了,所以首选innodb,存储方式是通过表空间的方式,5.5之前默认的是系统表空间,会导致各种麻烦(io瓶顶,性能),强烈建议使用独立的表空间更容维护,为改引擎设置主键时候应该尽可能遵守小,顺序增长的,还有主键和业务主键可以不同

  • 特性
  1. 支持事物
  2. 行级锁(在存储引擎层实现的),最大程度的支持并发

csv

适合作为数据交互的中间表

  • 特性
  1. 以csv格式进行数据存储
  2. 所有列都是 不能为空的
  3. 不支持索引,所以不适合大表和在线处理
  4. 可以对数据文件直接编辑,保存文本文件内容

Archive

日志和数据采集类应用

  • 特性
  1. 更少的的磁盘io占用
  2. 只支持insert和select操作(支持锁可以进行并发新增)
  3. 只允许在自增id列上加索引 

Memory

  • 特性
  1. 数据保存在运行内存中,所以一旦重启就会丢失数据但是表结构还会保存下来
  2. 支持hash索引(等值查询很快,范围查询不行)和btree索引(范围查询很快),不指定默认是hash索引
  3. 不支持大字段类型,字段固定长度是char(10)
  4. 使用表级锁(并发数辣鸡,性能不一定就比innodb好)
  5. max_heap_table_size参数来指定最大最小内存范围
  • 使用场景
  1. 用户查找或者是映射表,例如邮编和地区的对应表
  2. 用户报错数据分析中产生的中间表
  3. 用户缓存周期性聚合数据的结果表
  4. memory数据已丢失,所以要求数据可再生

federated

性能太差,默认被禁止了,可用于偶尔的统计分析及手工查询

  • 特性
  1. 提供了远程访问mysql服务器上表的方法
  2. 本地不保存数据,数据全部放到远程服务器上
  3. 本地需要保存表结构和远程服务器的连接信息

 

2:为字段设置合适的类型

整数类型:

实数类型:

如何选择varchar和char类型:

  • varchar的存储特点
  1. varchar用于存储变长的字符串,只占用必要的存储空间
  2. 列的最大长度小于255则只占用一个额外字节用于记录字符串长度,大于255则要占用2个
  3. varchar和char都是以字符为单位的(汉字)
  • varchar的长度选择问题
  1. 使用最小的符合需求的长度
  2. varchar(5)和varchar(200)存储字符如“波波”字符串的性能是不同的
  • char类型存储特点
  1. char类型是定长的
  2. 字符串存储在char类型的列中会删除末尾的空格
  3. char类型的最大宽度为255
  • char类型的使用场景
  1. char类型适合存储长度近似的值
  2. char类型适合存储短字符串
  3. char类型适合存储经常更新的字符串列

存储日期数据:

  • datetime
  1. 占用8个字符的存储空间,可以通过这样datetime(6)来指定存储带微秒的日期

   

  • date
  • time
  •  
  • timestamp
  1. 时间戳类型,存储时区到现在的秒数,占用4个字节
  2. 依赖时区,时区不一样,时间就不一样
  3. 列被修改时,会自动更新这个字段为修改时间,但是只会更新最前面的一个,可以在建表的时候进行指定

3:经验索引,sql优化

记录一下菜鸡的索引经验

对于sql用上表达式或函数索引是不会生效的,千万级的数据用上了索引也很慢,考虑其他方式(dba的事情)

对于一条sql多个条件我们可以使用联合索引规则如下:

  1. 经常会被使用到的列优先
  2. 选择性高的列优先,重复数据少代表选择性高,后面会有sql
  3. 宽度小的列优先

SELECT * FROM information_schema.PROCESSLIST ;可以实时获取有性能问题的sql

优化not in和<>

SELECT
    customer_id,
    first_name,
    last_name,
    email 
FROM
    customer 
WHERE
    customer_id NOT IN ( SELECT customer_id FROM payment );

优化后:
SELECT
    a.customer_id,
    a.first_name,
    a.last_name,
    a.email form customer a
    LEFT JOIN payment b ON a.customer_id = b.customer_id 
WHERE
    b.customer_id IS NULL

对于慢sql通过查看执行计划来进行优化

在sql前面加入explain 关键字即可获取执行计划

执行计划输出列:

  • id
  1. 因为有时候是多个表联合查询,所以要通过id来判断执行顺序,规则为:id相同时执行顺序是由上而下的,id不相同时候执行顺序是数字大小,数字大的优先级越高,
  • select_type
  1. simple 不包含子查询或者是uninon操作的查询
  2. primary 查询中如果包含任何子查询,那么最外层的查询则被标记为primary
  3. subquery select列表中的子查询
  4. dependent subquery 依赖外部结果的子查询
  • table
  1. 输出数据行所在的表的名称
  • prititions
  1. 对于分区表,显示查询的分区id,否则为null
  • type
  • 访问数据的方式,性能由高到低
  1. system 这是const链接类型的一个特例,当查询的表只有一行时使用
  2. const 表中有且只有一个匹配的行时使用,如对主键或是唯一索引的查询,这是效率最高的连接方式
  3. eq_ref 唯一索或主键引查找,对于每个索引键,表中只有一条记录与之匹配
  4. ref_or_null 类似于ref类型的查询,但是附加了对null值列的查询
  5. index_merge改连接类型表示是用来索引合并优化方法
  6. range索引范围扫描,常见于between,<,>这样的查询条件
  7. index  全索引扫描,同all的区别是,遍历的是索引树
  8. all   全表扫描
  • extra
  • 拓展列,使用的另外东西
  1. distinct 优化distinct操作,在找到第一个匹配的元组后即停止找同样值得动作
  2. not exists 使用not exists来优化查询
  3. using filesort 使用额外操作来进行排序,通常会出现在order by或group by查询中
  4. using index 使用了覆盖索引来查询
  5. using temporary mysql需要使用临时表来处理查询,常见于排序,子查询,和分组查询
  6. using where 需要mysql服务器层使用where条件来过滤数据
  7. select tables,optimized away 直接通过索引来获取数据,不访问表
  • possibile_keys
  • 可能会使用到的索引
  • key
  • 实际被使用的索引
  • key_len
  • 使用索引的总长度
  • ref
  • 表示那些列或常亮被用于查找索引列上的值
  • rows
  • 估算的所需读取的行数
  • filtered
  • 表示返回结果的行数占需读取行数的百分比,值越大越好,依赖于统计信息

获取audit ,product字段区分度sql,输出的值越靠近1说明区分度越大,就放在组合索引的前面

select count(distinct audit)/count(*) as a,

count(distinct product)/conut(*) as b from product_comment

创建组合索引:

create index name on tablename(a,b)

启用mysql慢查询来获取有问题的sql

set global slow_query_log_file =/sql/sql.log //设置路径

set global log_queries_not_using_indexes=on; //是否记录没有用到索引的sql

set global long_query_time=0.001; //超过多少秒的sql被记录

set global low_query_log=on; //开启日志

mysqldumpslow slow-mysql.log; //使用mysql自带的工具来分析日志,输出的结果是统计多次出现的sql便于我们快速定位

猜你喜欢

转载自blog.csdn.net/qq_35035078/article/details/82178680
今日推荐