一、表设计上的坑

  1、字段设计

  1.1 字段类型设计

    尽量使用整型表示字符串:

    `INET_ATON(str)`,address to number

    `INET_NTOA(number)`,number to address

  1.2 定长和非定长数据类型的选择

    1、decimal不会损失精度,存储空间会随数据的增大而增大。double占用固定空间,较大数的存储会损失精度。

    2、定长`char`,非定长`varchar、text`(上限65535,其中`varchar`还会消耗1-3字节记录长度,而`text`使用额外空间记录长度)字段长度不要设置过长,会占用空间。

  1.3 尽可能使用not null

    1、非null字段的处理要比null字段的处理高效些!且不需要判断是否为null。

    2、null在MySQL中,不好处理,存储需要额外空间,运算也需要特殊的运算符。如select null = null和select null <> null(<>为不等号)有着同样的结果,只能通过is null和is not null来判断字段是否为 null。

  1.4 单表字段不宜过多,可以参考使用预留字段,否则查找效率低下(分库分表)。

  2、范式要求 (降低数据冗余)

  • ​ 第一范式:字段原子性
  • ​ 第二范式:消除对主键的部分依赖
  • ​ 第三范式:消除对主键的传递依赖

二、常用存储引擎的选择(engine=***)

  MyISAM InnoDB
索引类型 非聚簇索引 聚簇索引
支持事务
支持表锁
支持行锁
支持外键
支持全文索引full text 是(5.6后支持)
适合操作类型 大量select 大量insert、delete、update

三、索引机制

  1、索引介绍

​   索引是帮助 MySQL 高效获取数据的数据结构。

  ​ 索引存储在文件系统中。

​   索引的文件存储形式与存储引擎有关。

  2、索引分类:

  mysql索引的五种类型:主键索引、唯一索引、普通索引和全文索引、组合索引。通过给字段添加索引可以提高数据的读取速度,提高项目的并发能力和抗压能力。

  主键索引

    主键是一种唯一性索引,但它必须指定为PRIMARY KEY,每个表只能有一个主键。如果没有主键,那么会选择唯一键,如果没有唯一键,那么会生成一个6位的row_id来作为主键。

  唯一索引

    索引列的所有值都只能出现一次,即必须唯一,值可以为空。

  普通索引

    基本的索引类型,值可以为空,没有唯一性的限制。

  全文索引

    全文索引的索引类型为FULLTEXT。全文索引可以在varchar、char、text类型的列上创建。

  组合索引

    多列值组成一个索引,专门用于组合搜索。索引采用最左原则。

  3、索引的数据结构

    hash、二叉树、红黑树、B树、B+树(为什么选用B+树请参考 https://www.cnblogs.com/jing99/p/11760993.html)

  4、索引的应用场景

  • where查询条件尽可能将索引列设置为条件表达式。
  • order by在查询的时候会使用索引列。
  • join on的条件列设置为索引列。
  • 索引覆盖:查询的列如果全部建立过索引,那么会直接查询索引,而不会查询全部数据。
  • 字段要独立出现:select * from user where id = 20-1; select * from user where id+1 = 20;
  • 模糊查询的时候,尽量不要将like语句匹配表达式以通配符开头 (like '%abc'),而是尽量采用 ('abc%),通配符开头会触发全文扫描。
  • 在使用状态值的时候不要创建索引。

四、缓存设置

  1、在配置文件中开启缓存

  在[mysqld]段中配置query_cache_size:

    0:不开启

    1:开启,默认缓存所有,需要在SQL语句中增加select sql-no-cache提示来放弃缓存

    2:开启,默认都不缓存,需要在SQL语句中增加select sql-cache来主动缓存(常用)

  2、在客户端设置缓存大小

  通过配置项 set global query_cache_size=64x1024x1024

五、数据分区

  单机情况下MySQL性能很高,但是当数据量较大并且是分布式访问的时候,MySQL的性能就开始下降,需要将数据分散到多组存储文件中,以保证单个文件的执行效率。

  分区算法:

  1、hash(field) 适用于整型字段

  ​2、key(field) 适用于字符串类型

​  3、range算法 按照数据大小范围分区

create table article_range(
id int auto_increment,
title varchar(64),
content text,
created_time int, -- 发布时间到1970-1-1的毫秒数
PRIMARY KEY (id,created_time) -- 要求分区依据字段必须是主键的一部分
)charset=utf8
PARTITION BY RANGE(created_time)(
PARTITION p201808 VALUES less than (1535731199), -- select UNIX_TIMESTAMP('2018-8-31 23:59:59')
PARTITION p201809 VALUES less than (1538323199), -- 2018-9-30 23:59:59
PARTITION p201810 VALUES less than (1541001599)    -- 2018-10-31 23:59:59
);

  4、list算法

create table article_list(
id int auto_increment,
title varchar(64),
content text,
status TINYINT(1), -- 文章状态:0-草稿,1-完成但未发布,2-已发布
PRIMARY KEY (id,status) -- 要求分区依据字段必须是主键的一部分
)charset=utf8
PARTITION BY list(status)(
PARTITION writing values in(0,1), -- 未发布的放在一个分区
PARTITION published values in (2) -- 已发布的放在一个分区
);
insert into article_list values(null,'mysql优化','内容示例',0);
flush tables;

六、集群

  1、主从复制

  mysql主从是异步复制过程

  • master开启bin-log功能,日志文件用于记录数据库的读写增删。
  • 需要开启3个线程,master IO线程,slave开启 IO线程、SQL线程。
  • Slave 通过IO线程连接master,并且请求某个bin-log,position之后的内容。
  • MASTER服务器收到slave IO线程发来的日志请求信息,io线程去将bin-log内容,position返回给slave IO线程。
  • slave服务器收到bin-log日志内容,将bin-log日志内容写入relay-log中继日志,创建一个master.info的文件,该文件记录了master ip 用户名 密码 master bin-log名称,bin-log position。
  • slave端开启SQL线程,实时监控relay-log日志内容是否有更新,解析文件中的SQL语句,在slave数据库中去执行。

  2、读写分离

  读写分离是依赖于主从复制,而主从复制又是为读写分离服务的。MySQL读写分离是指让master处理写操作,让slave处理读操作,非常适用于读操作量比较大的场景,可减轻master的压力。

  3、负载均衡

    轮询

    加权轮询

    负载分配

  4、高可用

  在服务器架构时,为了保证服务器7x24不宕机在线状态,需要为每台单点服务器(由一台服务器提供服务的服务器,如写服务器、数据库中间件)提供冗余机。

  对于写服务器来说,需要提供一台同样的写-冗余服务器,当写服务器健康时(写-冗余通过心跳检测),写-冗余作为一个从机的角色复制写服务器的内容与其做一个同步;当写服务器宕机时,写-冗余服务器便顶上来作为写服务器继续提供服务。对外界来说这个处理过程是透明的,即外界仅通过一个IP访问服务。

七、SQL语句优化

  1、数据库导入语句

    1.1、导入时先禁用索引和约束:

    alter table table-name disable keys

    待数据导入完成之后,再开启索引和约束,一次性创建索引

    alter table table-name enable keys

    1.2、数据库如果使用的引擎是innodb,那么它默认会给每条写指令加上事务(这也会消耗一定的时间),因此建议先手动开启事务,再执行一定量的批量导入,最后手动提交事务。

    1.3、如果批量导入的SQL指令格式相同只是数据不同,那么你应该先prepare预编译一下,这样也能节省很多重复编译的时间。

  2、limit offsets,row

  尽量保证不要出现大的offset,比如limit 10000,10相当于对已查询出来的行数弃掉前10000行后再取10行,完全可以加一些条件过滤一下(完成筛选),而不应该使用limit跳过已查询到的数据。

  3、select * 要少用

  即尽量选择自己需要的字段`select`,但这个影响不是很大,因为网络传输多了几十上百字节也没多少延时,并且现在流行的ORM框架都是用的`select *`,只是我们在设计表的时候注意将大数据量的字段分离。

  4、单表和多表查询

  多表查询:join、子查询都是涉及到多表的查询。如果你使用explain分析执行计划你会发现多表查询也是一个表一个表的处理,最后合并结果。因此可以说单表查询将计算压力放在了应用程序上,而多表查询将计算压力放在了数据库上。

  谓词下推:将外层查询块的 WHERE 子句中的谓词移入所包含的较低层查询块(例如视图),从而能够提早进行数据过滤以及有可能更好地利用索引的技术。

-- 有表如下:
-- t_student(student_id, student_name, student_age)
-- t_score(score_id, student_id, course_id, score_number) -- 优化前的SQL
SELECT *
FROM t_student,t_score
WHERE t_score.student_id=t_student.student_id
AND t_score.score_id=2; -- 优化后的SQL
SELECT * FROM t_student t1 right JOIN (
SELECT * from t_score WHERE score_id=2
) t2
ON t1.student_id=t2.student_id;

  5、count(*)

  在MyISAM存储引擎中,会自动记录表的行数,因此使用count(*)能够快速返回。而innodb内部没有这样一个计数器,需要我们手动统计记录数量。因此使用count(1)或者count(column)。

  6、开启慢查询日志

  配置项:slow_query_log

  可以使用 show variables like ‘slov_query_log’ 查看是否开启,如果状态值为OFF,可以使用 set GLOBAL slow_query_log = on来开启,它会在datadir下产生一个xxx-slow.log的文件。便于以后对SQL的慢查询执行优化。

八、MySQL配置

​   1、max_connections 最大客户端连接数

​   2、table_open_cache 表文件缓存

​   3、key_buffer_size 索引缓存大小

​   4、innodb_buffer_pool_size innodb存储引擎缓存池大小

​   5、innodb_file_per_table 将每一个表的数据放在一个文件中而不是共享表空间

MySQL常见问题集锦及注意事项的更多相关文章

  1. 20160924-2——mysql常见问题集锦

    一.数据类型相关问题 1.varchar(N)占用多少空间 (1)varchar(N)里的N是字符数,而不是字节数: (2)字符类型(varchar text blob等)空间=字符实际长度+字段长度 ...

  2. Mysql常见问题集锦

    缺少libstdc++.so.6库的原因及解决办法 https://blog.csdn.net/u010417185/article/details/69951312 https://www.cnbl ...

  3. (转)【面试】【MySQL常见问题总结】【03】

    [常见面试问题总结目录>>>] [面试][MySQL常见问题总结][03] 2016-05-29 22:20 阅读(8244) 评论(2) [面试][MySQL常见问题总结][02] ...

  4. VueJS 开发常见问题集锦

    由于公司的前端开始转向 VueJS,最近开始使用这个框架进行开发,遇到一些问题记录下来,以备后用. 主要写一些 官方手册 上没有写,但是实际开发中会遇到的问题,需要一定知识基础. 涉及技术栈 CLI: ...

  5. 30.Mysql常见问题和应用技巧

    30.Mysql常见问题和应用技巧30.1 忘记Mysql的root密码30.2 如何处理MyISAM存储引擎的表损坏 30.2.1 方法一:使用myisamchk工具 30.2.2 方法二:使用SQ ...

  6. mysql常见问题总结

    061 如何删除表? 答案:运行命令 drop table table_name; 062 创建索引 对于查询占主要的应用来说,索引显得尤为重要.很多时候性能问题很简单的就是因为我们忘了添加索引而造成 ...

  7. mysql 创建表时注意事项

    mysql  创建表时注意事项 mysql 想必大家都不会陌生吧  是我学习中第一个接触的的数据库 已学习就很快上手的   这是一个关系型数据库  不懂什么是关系型数据库 啊哈哈哈  现在知道啦  因 ...

  8. MySQL数据库使用时注意事项

    MySQL数据库使用时注意事项 建表的角度上 1.合理安排表关系 2.尽量把固定长度的字段放在前面 3.尽量使用char 代替varchar 4.分表:水平分和垂直分 在使用sql语句的时候 1.尽量 ...

  9. mysql索引设计的注意事项

    mysql索引设计的注意事项 目录 一.索引的重要性 二.执行计划上的重要关注点 (1).全表扫描,检索行数 (2).key,using index(覆盖索引) (3).通过key_len确定究竟使用 ...

随机推荐

  1. Spring cloud微服务安全实战-3-10API安全机制之授权

    说一下最后一个模块,授权.用来做访问控制,控制哪个用户能干什么.哪个用户不能干什么? 遵循最小的授权原则,一个用户只给他必须要的那些权限. 1.你的请求是不是需要权限认证, 有一些请求是根本不需要权限 ...

  2. ES6深入浅出-10 ES6新增的数据类型-1.Symbol与隐藏属性

    ES5现有的数据类型.7种数据类型. 新的类型是属于Object 最普通的类型.plain object 数组array 函数function 下面这些都属于Object类型. 今天要讲的 set类型 ...

  3. mysql登录指令

    mysql -h 192.168.1.124 -u root -p -h后加mysql的ip,-u加用户名,-p会弹出输入密码

  4. extends 类的继承 / super关键字,调用继承类里面的函数和变量

    Son 继承Father 当其他脚本想调用 Father类里面的变量 or 方法 可以把 Son r=new Son()   等价于 Father r=new Father() 注意: 函数只能单继承 ...

  5. PLSQL集合类型的使用总结

    PLSQL集合类型的使用总结 在pl sql 中,集合(collection) 是一组有序的元素组成的对象,这些元素的类型必须一致. pl sql 将collection 分成3 类,分别为Assoc ...

  6. Xray写POC插件

    漏洞环境 https://www.vulnhub.com/ https://github.com/vulhub/vulhub https://github.com/QAX-A-Team/Weblogi ...

  7. Tomcat教程(转)

    转载链接: https://www.cnblogs.com/jingmoxukong/p/8258837.html?utm_source=gold_browser_extension 简介 Tomca ...

  8. 文件描述符FD的含义/文件句柄

    使用sudo lsof -nP -iTCP -sTCP:LISTEN查看占用端口的程序;因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能 概念 ...

  9. Django2.2_No installed app with label 'admin'

    版本:py37+django2.2 错误:项目启动时出现,No installed app with label 'admin' 原因:可以发现只要注释掉settings里面的数据库DATABASES ...

  10. Echart timeline 高级用法!!!!

    一.前言 在使用 echart timeline 来着图形可视化时,我使用的和官网也不一样,因为我有使用映射关系.比如我将 no 映射到X轴,将 d4 映射到Y轴. 二.参考 echart官网:htt ...