目录
1:体系结构和常用的存储引擎的优劣:
myisam
- 特性:
- 他是表级锁,插入新数据时候会进行锁表,查询操作时候会加入共享锁,所以他的查询和新增是互斥的一个操作,并发的话。
- 它支持任何方式的损坏修复操作,但是不是事物它不支持事物 (check table tablename,repair table tablename)。
- 5.5版本之前原生支持全文索引,还对大字段类型的前500字符建立索引,全文索引不能优化like '%%'这种检索,他是通过分词来查询数据的。
- 可以进行数据压缩(myisampack命令),减少磁盘io占用,但是压缩后无法对数据进行新增更新操作。
- 使用场景:
- 非事务型应用
- 只读类应用
- 空间类应用
Innodb
默认,免费的热部署备份数据方案,5.6版本的都支持全文索引和空间类函数了,所以首选innodb,存储方式是通过表空间的方式,5.5之前默认的是系统表空间,会导致各种麻烦(io瓶顶,性能),强烈建议使用独立的表空间更容维护,为改引擎设置主键时候应该尽可能遵守小,顺序增长的,还有主键和业务主键可以不同
- 特性:
- 支持事物
- 行级锁(在存储引擎层实现的),最大程度的支持并发
csv
适合作为数据交互的中间表
- 特性:
- 以csv格式进行数据存储
- 所有列都是 不能为空的
- 不支持索引,所以不适合大表和在线处理
- 可以对数据文件直接编辑,保存文本文件内容
Archive
日志和数据采集类应用
- 特性:
- 更少的的磁盘io占用
- 只支持insert和select操作(支持锁可以进行并发新增)
- 只允许在自增id列上加索引
Memory
- 特性:
- 数据保存在运行内存中,所以一旦重启就会丢失数据但是表结构还会保存下来
- 支持hash索引(等值查询很快,范围查询不行)和btree索引(范围查询很快),不指定默认是hash索引
- 不支持大字段类型,字段固定长度是char(10)
- 使用表级锁(并发数辣鸡,性能不一定就比innodb好)
- max_heap_table_size参数来指定最大最小内存范围
- 使用场景:
- 用户查找或者是映射表,例如邮编和地区的对应表
- 用户报错数据分析中产生的中间表
- 用户缓存周期性聚合数据的结果表
- memory数据已丢失,所以要求数据可再生
federated
性能太差,默认被禁止了,可用于偶尔的统计分析及手工查询
- 特性:
- 提供了远程访问mysql服务器上表的方法
- 本地不保存数据,数据全部放到远程服务器上
- 本地需要保存表结构和远程服务器的连接信息
2:为字段设置合适的类型
整数类型:
实数类型:
如何选择varchar和char类型:
- varchar的存储特点
- varchar用于存储变长的字符串,只占用必要的存储空间
- 列的最大长度小于255则只占用一个额外字节用于记录字符串长度,大于255则要占用2个
- varchar和char都是以字符为单位的(汉字)
- varchar的长度选择问题
- 使用最小的符合需求的长度
- varchar(5)和varchar(200)存储字符如“波波”字符串的性能是不同的
- char类型存储特点
- char类型是定长的
- 字符串存储在char类型的列中会删除末尾的空格
- char类型的最大宽度为255
- char类型的使用场景
- char类型适合存储长度近似的值
- char类型适合存储短字符串
- char类型适合存储经常更新的字符串列
存储日期数据:
- datetime
- 占用8个字符的存储空间,可以通过这样datetime(6)来指定存储带微秒的日期
- date
- time
- timestamp
- 时间戳类型,存储时区到现在的秒数,占用4个字节
- 依赖时区,时区不一样,时间就不一样
- 列被修改时,会自动更新这个字段为修改时间,但是只会更新最前面的一个,可以在建表的时候进行指定
3:经验索引,sql优化
记录一下菜鸡的索引经验
对于sql用上表达式或函数索引是不会生效的,千万级的数据用上了索引也很慢,考虑其他方式(dba的事情)
对于一条sql多个条件我们可以使用联合索引规则如下:
- 经常会被使用到的列优先
- 选择性高的列优先,重复数据少代表选择性高,后面会有sql
- 宽度小的列优先
SELECT * FROM information_schema.PROCESSLIST ;可以实时获取有性能问题的sql
优化not in和<>
SELECT
customer_id,
first_name,
last_name,
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
- 因为有时候是多个表联合查询,所以要通过id来判断执行顺序,规则为:id相同时执行顺序是由上而下的,id不相同时候执行顺序是数字大小,数字大的优先级越高,
- select_type
- simple 不包含子查询或者是uninon操作的查询
- primary 查询中如果包含任何子查询,那么最外层的查询则被标记为primary
- subquery select列表中的子查询
- dependent subquery 依赖外部结果的子查询
- table
- 输出数据行所在的表的名称
- prititions
- 对于分区表,显示查询的分区id,否则为null
- type
- 访问数据的方式,性能由高到低
- system 这是const链接类型的一个特例,当查询的表只有一行时使用
- const 表中有且只有一个匹配的行时使用,如对主键或是唯一索引的查询,这是效率最高的连接方式
- eq_ref 唯一索或主键引查找,对于每个索引键,表中只有一条记录与之匹配
- ref_or_null 类似于ref类型的查询,但是附加了对null值列的查询
- index_merge改连接类型表示是用来索引合并优化方法
- range索引范围扫描,常见于between,<,>这样的查询条件
- index 全索引扫描,同all的区别是,遍历的是索引树
- all 全表扫描
- extra
- 拓展列,使用的另外东西
- distinct 优化distinct操作,在找到第一个匹配的元组后即停止找同样值得动作
- not exists 使用not exists来优化查询
- using filesort 使用额外操作来进行排序,通常会出现在order by或group by查询中
- using index 使用了覆盖索引来查询
- using temporary mysql需要使用临时表来处理查询,常见于排序,子查询,和分组查询
- using where 需要mysql服务器层使用where条件来过滤数据
- 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便于我们快速定位