MySql数据库select的执行过程、连接语句、范式等

  1. Mysql种执行select时,数据库处理指令的流程:

    1、FORM: 对FROM左边的表和右边的表计算笛卡尔积,产生虚表VT1。
    2、ON: 对虚表VT1进行ON过滤,只有那些符合<join-condition>的行才会被记录在虚表VT2中。
    3、JOIN: 如果指定了OUTER JOIN(比如left join、 right join),那么保留表中未匹配的行就会作为外部行添加到虚拟表VT2中,产生虚拟表VT3。
    4、WHERE: 对虚拟表VT3进行WHERE条件过滤。只有符合<where-condition>的记录才会被插入到虚拟表VT4中。
    5、GROUP BY: 根据group by子句中的列,对VT4中的记录进行分组操作,产生VT5。
    6、HAVING: 对虚拟表VT5应用having过滤,只有符合<having-condition>的记录才会被 插入到虚拟表VT6中。
    7、SELECT: 执行select操作,选择指定的列,插入到虚拟表VT7中。
    8、DISTINCT: 对VT7中的记录进行去重。产生虚拟表VT8.
    9、ORDER BY: 将虚拟表VT8中的记录按照<order_by_list>进行排序操作,产生虚拟表VT9.
    10、LIMIT:取出指定行的记录,产生虚拟表VT10, 并将结果返回。

  2. 连接语句,条件放在on后面和放在where后面的区别:
    比如两张表A,B,A种5条数据,B中5条数据,A,B中数据一一对应,B中有一个字段status,前三条值为1,后两条值为2,问下面语句分别可以查出多少条数据:
    (1)select * from A left join B on B.status=1 where A.name=B.name;
    (2)select * from A left join B where A.name=B.name AND B.status=1;
    这里考察的正是语句的执行顺序,答案是:(1)查出来5条,(2)查出来3条
    原因是:on会先对连接的B表做筛选过滤,(1)中此时B表相当于只有3条数据,然后和5条数据的A表做链接,由于是一一对应的,所以查出来就是常规的5条数据;(2)中没有on此时是A5条数据和B5条数据做连接得到5条连接后的数据,再做where的筛选,此时5条中只有3条status=1,所以(2)查出来是3条。

  3. 数据库的三范式:
    第一范式(1NF):第一范式是指数据库表中的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。
    第二范式(2NF):满足1NF后,表必须有一个主键,二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
    第三范式(3NF):必须先满足第二范式(2NF),消除非主属性的传递函数依赖;
    简单说就是:一范式要求,列的功能要唯一不可分,比如一个表有个电话的字段,电话又分为手机和固话,此时只用电话来表示该字段就不满足一范式。二范式要求列完全依赖于主键,这句话隐含着列不能部份依赖,比如,学生+课程决定了书籍,学生+课程是联合主键,只靠课程如果也可以决定书籍的话,那么这就不满足二范式。三范式要求没有以来传递,比如 学生+课程 可以确定老师,老师又可以确定老师的职称,那么,老师和职称就不能放在学生课程表里,因为如果老师职称提升了,就需要修改每一条选课记录,而不是只改一次。

  4. 哪些不当用法会导致放弃索引而进行全表扫描:
    1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值。
    2.应尽量避免在 where 子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描。
    3.应尽量避免在 where 子句中使用or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num=10 or num=20可以这样查询:select id from t where num=10 union all select id from t where num=20。
    4.in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了。
    5.下面的查询也将导致全表扫描:select id from t where name like ‘%李%'若要提高效率,可以考虑全文检索。
    6.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:select id from t where num/2=100应改为:select id from t where num=100*2。

  5. 聚簇索引和非聚簇索引:
    MySQL索引使用的数据结构主要有BTree索引 和 哈希索引 。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。MySQL的BTree索引使用的是B数中的B+Tree,但对于主要的两种存储引擎的实现方式是不同的。MyISAM: B+Tree叶节点的data域存放的是数据记录的地址。在索引检索的时候,首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其 data 域的值,然后以 data 域的值为地址读取相应的数据记录。这被称为“非聚簇索引”。InnoDB: 其数据文件本身就是索引文件。相比MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按B+Tree组织的一个索引结构,树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这被称为“聚簇索引(或聚集索引)”。而其余的索引都作为辅助索引,辅助索引的data域存储相应记录主键的值而不是地址,这也是和MyISAM不同的地方。在根据主索引搜索时,直接找到key所在的节点即可取出数据;在根据辅助索引查找时,则需要先取出主键的值,再走一遍主索引。 因此,在设计表的时候,不建议使用过长的字段作为主键,也不建议使用非单调的字段作为主键,这样会造成主索引频繁分裂。 PS:整理自《Java工程师修炼之道》

  6. 大量文件导入数据库怎么做:
    使用批处理,可以减少事务的开销。

猜你喜欢

转载自blog.csdn.net/u013821237/article/details/93158715