mysql数据库基础
Posted 记录点点滴滴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql数据库基础相关的知识,希望对你有一定的参考价值。
1 内连接与外连接
内连接(inner join)与外连接的区别是内连接仅仅筛选匹配中的数据,而外连接会选出其他不匹配的数据。具体使用内链接还是外连接 看业务和习惯吧。
2 子查询
当进行查询时候,需要的条件是另外一个select语句的结果,这时候需要用到子查询,关键字是 in , not in, = , !=, exists ,not exists等
如果子查询结果只有一条 ,也可以使用 = 代替in
有些情况,子查询可以转化为表连接,转表连接可以优化子查询。
3 union , union all
作用都是合并结果集,union 是union all后的结果进行一次distinct 去除重复记录的结果。
4 mysql数据类型
数值 在定义数值字段时,会有一个宽度 如int(5),这个宽度是配合zerofile使用的,意思是当数据宽度不足5的时候 在数字前面使用0填充。
字符
char与varchar的区别,char 会删除尾部的空格而varchar不会,char是固定长度的字符类型,varchar是可变长的字符类型。
该如何选择字符串类型? 对于常用的InnoDB引擎,建议使用varchar,对于InnoDB 数据表 内部存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此本质上 使用固定长度的char 不一定比可变长度的varchar性能要好,主要性
能因素还是数据行的存储总量。
TEXT 与BLOB
这两种主要用于存储大文本的,区别是 TEXT 只能保存字符数据 如文章或者日记,BLOB 用来存二进制数据 如照片 视频等等。这两种类型会造成一定的性能问题
5 mysql各种运算的优先级,实际工作中 可以直接使用(),将需要优先的操作括起来
6 mysql函数
常用函数有 字符串函数,数值函数 ,日期和时间函数,流程函数等等。下面看看流程函数语法
7 两种主要存储引擎的比较
InnoDB 支持事务,效率比MyISAM低一些,锁等级是行锁。
MyISAM 不支持事务,效率比较高,锁等级锁表锁。
8 浮点数(float,double)与定点数(decimal)
对于浮点数 当插入数据的精度超过定义的实际精度,会自动被四舍五入然后插入数据库
对于定点数 定点数实际是一字符串的形式存放的,所以可以精确的存放数据
使用浮点数可能出现误差,上面可以看出来, 所以尽量使用decimal
9 sql优化
1 定位执行效率低的sql语句,使用--log-slow-queries[=file_name]选项启动时,mysql会写入一个所有包含 执行时间超过long_query_time秒的日志文件。
2 使用以上步骤查询到效率低的sql语句之后,通过explain或者desc命令获取mysql的执行计划,执行计划包括执行过程中 表如何连接和连接的顺序等等信息。
输出字段解释
select_type 查询类型 SAMPLE(简单表,即不使用表连接或者子查询), PRIMARY(主查询,即外层查询),UNION(UNION中的第二个,或者后面的子查询),SUBQUERY(子查询中的第一个select)
table 输出结果集的表
type 访问类型 性能从差到好依次是 ALL < index < range < ref < eq_ref < const,system < NULL
ALL 全表扫描(mysql遍历全表来查找匹配行),index (mysql遍历整个索引来查询匹配行),range(索引范围查找,常见于 < <= > >= between等),ref (使用非唯一索引扫描或唯一索引的前缀扫描 返回某个单独值的记录行),eq_ref (类似于 ref,区别:百度),const,system (单表中最多有一个结果行 速度很快,如根据主键或者unique key 来查询),NULL (不扫描表或者索引就得到结果 , 如select 1 from test)
possible_keys 可能使用到的索引
key 实际使用的索引
key_len 使用到的索引字段的长度
rows 扫描行的数量
Extra 执行计划的说明
3 通过show profile来分析sql 这个有点复杂呀我日, 参考https://blog.csdn.net/taojin12/article/details/81349112
4 通过trace分析优化器分析mysql执行器的行为 这个也有点难 参考https://blog.csdn.net/taojin12/article/details/81489234
5 索引 主要使用的索引就是BTREE索引 其他索引不讨论
mysql中使用索引的典型场景
1 匹配最左前缀 ,最左前缀原则可以说是mysql中B-TREE索引使用的首要原则。
假设一个联合索引包含三列(col1 ,clo2 clo3), 那么可以使用 col1,(col1 + col2),(clo1 +col2 +clo3),(col1 + col3)查询利用到,对于(col2) ,(col2,col3)则不会用到
2 全值匹配:和索引中的所有列进行匹配
3 匹配值的范围查询,多索引的值进行范围查找 如cusomer_id > 11 and customer_id < 100
4 进对索引列进行查询 ,当需要查询的列都在索引的字段时 查询效率更高, 下面的Extra部分变成了 Using index ,意味着 直接访问索引就足够取数据了 不需要通过索引再去表查询
5 匹配列前缀 仅仅使用索引的第一列 并且只包含第一列的开头一部分进行查找。User where 表示需要通过索引回表查询数据。
存在索引 但是不能使用索引的主要典型场景
1 以%开头的like查询不会使用索引 (这个可以使用全文索引来解决类似全文检索问题)
2 数据类型出现了隐式转换的时候不会使用索引,
3 联合索引的情况下,假设 查询条件不包含索引的最左列部分(不满足最左前缀原则), 不会使用符合索引。
4 用or 分开的条件 如果or前的条件列有索引 而后面的列无索引 ,那么涉及到的索引都不会被用到
常见的sql优化
1 批量的insert操作,这样可以减少客户端与数据库之间的连接,关闭 等消耗,比多个单insert 插入快很多,当然 也需要结合jdbc的批处理技术 一起使用。
2 优化order by
数据脚本文件是 http://downloads.mysql.com/docs/sakila-db.zip
mysql 有两种排序方式,第一种是通过有序索引顺序扫描直接返回有序数据,这种操作效率很高
第二种是对返回的数据进行排序,这也叫Filesort排序,所有不是通过索引直接返回排序结果的排序都叫Filesort排序,排序操作有可能是使用磁盘文件 也可能是临时表 具体取决于mysql服务器的排序参数。
根据以上的两种方式描述,我们的优化目标是 尽量减少额外的排序,通过索引返回有序的数据,where 和order by使用相同的索引 并且order by的顺序和索引的顺序相同 ,并且尽量都是升序或者降序 否是会出现filesort。
3 优化group by
默认情况下,mysql对所有 group by col1 ,clo2 ...的字段排序,这与查询中 指定order by clo1,col2...相似。 因此如果显式包含一个相同order by 子句,则对执行性能无影响。
第一个使用filesort ,第二个不使用filesort,使用filesort的时候 往往是比较消耗时间的。
4 优化嵌套查询
mysql4 .1开始支持子查询,子查询可以一次性的完成很多逻辑上需要多个步骤的sql操作,同时也可以避免事务或者表锁死,但是有些情况下可以使用表连接查询来替代子查询。连接查询之所以比子查询效率高,是因为mysql无需在内存中建立临时表来完成逻辑上需要两个步骤的查询。
可以看到index_subquery 调整为了ref。效率更好一点。
5 优化OR条件查询
如果要利用索引,那么 or之间的条件都必须用到索引才行,如果没索引 可以考虑加索引。
6 优化分页查询 limit比较头疼,比如 limit 1000,20 mysql 需要排序出前1020条记录,然后仅仅需要返回1001条到1020条记录,前面1000条记录都会被抛弃,随着数据量越来越大 所消耗的时间会越来越长,查询和排序的代价都非常高。
第一种优化思路,增加上一页的最后一行主键id值,比如 15640 ,
可以看的出来,这种方法不是一个很完美的解决方法,它要求主键有序,对于非主键有序(比如uuid)的场景不适用。另外这个这个查询结果依赖于上一页的结果 那假设用户想从第2页跳到第100页呢? 谁来提供第99页的最后一行主键id值?
第二种思路,使用主键来做 这个地方先去网上搜一下吧
10 优化表结构
主要 冷热数据分离 ,数据适当冗余 以及使用中间表
11 mysql 锁
表锁:表锁有两种模式:共享读锁,独占写锁。mysql 在执行select前 会自动给表加读锁,在执行 uddate delete insert之前 会自动给表加写锁。
共享读锁不会阻塞其他用户的读请求,但是会阻塞对同一个表的写请求。
独占写锁即会阻塞其他用户的读请求,也会阻塞写请求。
InnoDB 锁
以上是关于mysql数据库基础的主要内容,如果未能解决你的问题,请参考以下文章