文章四大部分基础知识、性能优化(索引、sql 查询)、高并发大表、mysql 集群中间件,哎.....整理不易,看完觉着有帮助给个赞和小星星。
常见的数据类型有整数、浮点数、字符串、枚举、日期、列属性
varchar 是伸缩长度,char 是固定长度,如果存储手机号或者身份证号等固定长度的数据使用 char,存储名字或者文章标题类形不确定长度的数据使用 varchar。
char 和 varchar 后面数字是字符的长度,所以不管汉字还是英文还是数字都可以存4个。
因为单独设置 varchar(4)没有超出行字符串长度最大字节数,varchar(65535)超出了,utf8 一个字符=3 个字节。65535是每行最大字节数限制。
utf8mb4一个字符最大是3 个字节,utf8 是三个,可以存常用的文字英文数字,mb4 最大是 4 个可以存各种符号表情、生僻字等。
精度不同,double是双精度,float是单精度。
int(10) 无符号,无符号是 0-最大值,不设置无符号会扩大一倍浪费空间。
唯一索引:具备的唯一性和约束性,常用于手机号、身份证、unid 等不可重复的数据字段,加强数据的唯一性,而且允许有一个 null 值,在 MySQL 中,多个 NULL
值在唯一索引中被视为不重复)。缺点是 在数据进行插入和更新时候,需要额外检查唯一性约束,因此相对普通索引会有一些性能开销。
普通索引:普索引主要是为了增加数据的查询速度,适用于经常用于 WHERE
子句、JOIN
条件或者 ORDER BY
子句中的列。可以是单列索引,也可以是多列组合索引。在创建普通索引时,要考虑列的选择性(值的基数),选择性低的列(如性别、状态列)创建索引可能效果不佳。
全文索引:主要用于在文本类型的列(如 CHAR
、VARCHAR
或 TEXT
)上进行全文搜索,MyISAM 和 InnoDB 都支持全文索引,但在功能和性能上有一些差异。
空间索引:用于对空间数据(如地理坐标、几何图形等)进行索引,常见于地理信息系统(GIS)应用中。例如,在地图应用中,可以对地点的经纬度信息创建空间索引,以便快速查找附近的地点。
9、mysql 的事务和锁
可以将索引类比为书籍的目录,通过目录可以快速定位到书中具体内容所在的页码
通俗的讲 因为索引会对数据进行分类,就和书的目录一样,先找到目录再去找数据。目录是存在内存中的,大大的提高了查询效率。
专业点儿讲就是索引使用了b+tree数据结构,一般面试你试图讲这个玩意儿那将是讲也讲不清楚,说也说不明白,看也看不懂,好吧。。。作为一名合格严谨的程序员不能这样,用动图讲解 MySQL 索引底层B+树,清晰明了多了_51CTO博客_mysql底层是b+树这个文章我看还是比较好理解,反正数据结构包括机器学习这些,看完了?嗯,看完了,看懂了?好像有点儿。。。哎,继续努力吧,你(包括我)和大佬的差距可能就在这个地方。。。一步之遥却是鸿沟。。。
使用普通索引还是全文索引取决于具体的查询需求和使用场景,如果是精确查找如 where titile = ‘title’ ,使用普通索引效率会更高,如果使用LIKE '%关键词%'这种包含通配符在开头的模糊查询,普通索引将无法使用,数据库需要进行全表扫描,性能会大幅下降。在全文搜索场景下全文索引可以通过MATCH...AGAINST特定的查询语句进行,它使用倒排索引结构,能够快速定位包含关键词的文档,避免了全表扫描。所以如果系统追求高性能,可以使用 es 进行全文搜索,而且它的等值查找性能也很高。
(1)组合索引最需要考虑的是 sql 语句,where 的 列,我觉着数据库不能完全适配业务的 sql 查询,因为实际工作中会有很多复杂的查询场景,如果全部适配是不可行的,所以数据库组合索引只需要遵循自己的原则。
(2)组合索引的列顺序,需要遵循选择性高的列放在前面,这样可以更快的过滤掉大量的数据。
可以在批量插入数据之前暂时禁用索引,插入完成后再重新启用,以提高插入效率。
-- 禁用索引
ALTER TABLE table_name DISABLE KEYS;
-- 批量插入数据
INSERT INTO table_name (column1, column2, ...) VALUES (...);
-- 启用索引
ALTER TABLE table_name ENABLE KEYS;
(1)首先通过慢查询日志获取到 sql 语句,然后使用EXPLAIN关键字查看索引是否命中,还有是否进行了全表扫描type=all则表示进行了全表扫描。
(2)如果不是这个原因就需要考虑是否服务器资源问题,如:cpu 使用过高、内存使用过高、磁盘 I/O 性能低下,还有就是mysql 的参数配置是否合理,如innodb_buffer_pool_size(InnoDB 存储引擎的缓冲池大小)这些值设置不合理也可能影响查询效率。
(3)mysql 是否并发连接数比较多,如果是只能考虑 mysql 集群架构或者使用缓存技术降低 mysql 的压力。
(4)如果数据表特别大,可以考虑使用数据分区技术将数据分散存储在不同的分区中。这样可以减少查询时需要扫描的数据量,提高查询性能。
(5 )问题延生,可以使用 mysql 监控工具进行更加方便的管理,如sql server(商用收费)Grafana + Prometheus(免费开源),怎么用?....俺没用过。
索引的优化知识点好像整理完了,完了吗?好像还有一个 使用 ANALYZE TABLE your_table ,定期更新索引的统计信息。
还有一个问题唯一索引和普通索引的区别,今天面试问到了,我的回答是唯一索引具有唯一性,普通索引允许有重复值,额.....这个回答是不是太肤浅了.....
通常行数少于 1000的没必要建立,1000 - 100000 的 可以建立增加查询效率, 亿级别的了,单纯的索引解决不了所有查询效率问题,光索引文件的大小可能会达到数GB 甚至更大,尤其是 group 分组会很慢很慢.....几十秒,但是如果等值查询例如 order 表 订单号可以毫秒级别的响应。