sql知识点&查询优化

1,多表连接

    内连接:内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行

               实例: (隐式)select * from A, B where A.id=B.id     (1)

                           (显式)select * from A inner join B on A.id=B.id    (2)

    外连接:left join(left outer join)和 right join(right outer join)

                1)left join或left outer join  左向外联接的结果集包括 left join子句中指定的左表(A表)的所有行,而不仅仅是联接列所                         匹 配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。                                 例:select * from A left join B on A.id=B.id   
                2)right join或 right outer join    右向外联接是左向外联接的反向联接。将返回右表(B表)的所有行。如果右表的某行在                       左表中没有匹配行,则将为左表返回空值。    

                     例:select * from A right join B on A.id=B.id      
                3)full join  或 full outer join  完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表                       的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。   

     交叉连接:cross join  交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积

                    实例: (隐式)select * from A, B where A.id=1     (1)

                                (显式)select * from A cross join B where A.id=1    (2)

     联合连接:当前mysql和orcal都不支持,其作用是:找出全外连接和内连接之间差异的所有行

 

2,where条件 和 left/right join on条件区别

      ON条件:是形成临时表的约束条件

     WHERE条件:在有ON条件的SELECT语句中是过滤临时的约束条件。在没有ON的单表查询中,是限制物理表或者中间查                              询结果返回记录的约束。在两表或多表连接中是限制连接形成最终中间表的返回结果的约束。

                           例:select * from A left join B on A.id= B.id where id= XXX

3,索引失效情形,进而全表扫描(查询语句中出现where条件才会使用到索引,mysql支持B-Tree索引和Hash索引)

      1)如果where查询条件中有or,即便其中部分条件设置了索引。如果想使用or,又想让索引生效,则需要让or条件中的每个列都加上索引

      2)以%开头的like查询(模糊查询),索引失效

      3)数据库列被定义为字符串,查询时,where查询条件使用该列没有加引号,索引失效

      4)单独引用复合索引里非第一位置的索引列。当索引是建立在多个列上, 只有在它的第一个列被where子句引用时,优化器才       会选择使用该索引

      5)mysql估计使用全表扫描优于使用索引,此时索引失效

      6)where查询条件中出现运算符号、<> 、not in 、not exist、!=、或者使用内部函数,如有需要,这种情况下应该对函数建立索引

           eg: create index name_func on table_name(upper(name) )

     7)表连接(即join操作)时,当表主键外键数据类型相同,设置的索引才会生效

4,数据库结构优化

     1)分表,将字段很多(查询低效)的表分解多表,尤其将那些使用频率很低的字段分离出来形成新表

     2)增加中间表,从业务需求出发考虑,如果经常需要多表连接查询,那么建立中间表去存储那些经常连接查询的数据,这样             可以提升查询效率

5,分解关联查询

       就是将一个复杂的多表联合查询分解为多个简单的单表查询。很多高性能的应用都会用到这个方法。关联查询进行分解将单表查询的结果在应用程序中进行关联,在很多场景下这样做会更高效。  1)数据在应用层面进行关联,意味着数据库就方便拆分,这有助于扩展和高性能的实现。2)简单查询的效率本身效率就是相对更高的。3)缓存效率更高,对于多表联合查询,只要其中一个表发生变动,之前的缓存就没用了。但对于单表查询,只要更新改动表的数据就够了。4)减少冗余记录,在应用层做关联查询,所有用到的数据只要查询一次就够了,但如果是多表关联查询可能会重复访问某表数据。

6,limit M, N 分页优化

     常见的分页是由Limit加上偏移量实现,但如果偏移量很大的情况下(M很大),扫描前M+N条,然后扔掉前M条,返回后M条         数 据,这样的效率是很糟糕的。eg:select * from table_name limit 800000,20

     最直接的做法就是利用覆盖索引,也就是对所有查询的字段都添加索引。一般来说表的主键id都是默认添加了索引的,那么           select id from table_name limit  800000,20 的效率是不错的。但是如果就是要查询所有列的信息呢,上述应该修改为:select       *  from table_name where id >=(select id from table_name limit 800000, 1) limit 20, 更好点的写法 select * from table_name         where id between 800000,800020,那如果id 并非自增连续的呢?此时考虑in 查询select * from table_name where id                   in(800000,800001,...)

7,in 和exists

      in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询;如果查询的两个表大小相            当,那么用in和exists差别不大;如果两个表中一个较小一个较大,则子查询表大的用exists,子查询表小的用in;尽量不要使        用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则        查询将不返回任何记录;in不对NULL进行处理 

 

你可能感兴趣的:(sql知识点&查询优化)