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 锁

      

   

     

原文地址:https://www.cnblogs.com/tjqBlog/p/10251065.html