《数据库》小结02

一、SQL题

1.学生成绩表,把每科最高分前三名统计出来
成绩表Score(student_no,subject_no,score)

-分组排序函数:
函数名() over(partition by 分组列 order by 排序列 desc) 重命名列

  • rank() :并列时下一位空出所占的名次1,2,2,4。
  • dense_rank():并列时下一位不空出所占的名次1,2,2,3。
  • row_number():不需要考虑是否并列,哪怕根据条件查询出来的数值相同也会进行连续排名。
解法1:相关子查询
SELECT *
FROM Score AS s1
WHERE score in(
              Select score
              From Score As s2
              WHERE s2.subject_no = s1.subject_no and rownum<=3
              )
 order by s1.subject_no,s1.score desc;

解法2:分组排序函数
SELECT *
FROM ( SELECT *,row_number() over(partition by subject_no order by score desc) rank
       FROM Score 
       )
 WHERE rank<=3;

2.选出每个人成绩的最高的前两条纪录
成绩表Score(student_no,subject_no,score)

SELECT *
FROM ( SELECT *,rank() over(partition by student_no order by score desc) rank
       FROM Score
       )
WHERE rank<=2;

3.删除订单表中重复的记录

DELECT FROM Score
WHERE name IN(SELECT name
              FROM Score
              GROUP BY name
              HAVING count(name)>1)
AND ID NOT IN(SELECT MIN(ID)
              FROM Score
              GROUP BY name
              HAVING count(name)>1)

4.查询A表有但是B表没有

解法1:相关子查询
SELECT DISTINCT A.ID
FROM A
WHERE A.ID NOT IN ( SELECT ID
                    FROM B
                    )
解法2:左连接
SELECT A.ID
FROM A LEFR JOIN B ON A.ID=B.ID
WHERE B.ID IS NULL

5.找出单科成绩高于该科平均成绩的同学名单(无论该学生有多少科,只要有一科满足即可)

SELECT * 
FROM (SELECT *,AVG(score) over(partition by subject_no) flag
      From Score
      ) AS t
 WHERE score>t.flag

6.找出单科成绩高于该科平均成绩的同学名单(该学生所有科都必须满足)

SELECT DISTINCT a.name
FROM Score AS a 
LEFT JOIN( SELECT *
           FROM(SELECT *,AVG(score) over(partition by subject_no) flag
                FROM Score
                )AS t
            WHERE t.flag<=score
            ) AS b 
 ON a.name=b.name and a.subject_no = b.subject_no and a.score=b.score and b.score is not NULL; 

二、数据库索引

1.索引的作用和优点

  • 1.提高数据的查询检索速度
  • 2.通过创建唯一性索引可以保证数据库中每一行的唯一性
  • 3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
  • 4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
  • 5.通过使用索引,可以在查询的过程中,使用查询优化器,提高系统的性能。

2.索引的缺点

  • 1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
  • 2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
  • 3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

3.索引的类型
索引有两个特征,即唯一性索引和复合索引

  • 唯一索引:每一列都唯一
  • 主键索引:主键唯一,其余列可以相同
  • 聚簇索引和非聚簇索引
    ----表中行的物理顺序与键值的逻辑(索引)顺序相同,升序排列。每个表只有一个聚簇索引。
    ----与非聚簇索引相比,聚簇索引查询速度更快。在创建任何非聚簇索引之前创建聚簇索引,这是因为聚簇索引改变了表中行的物理顺序,数据行按照一定的顺序排列,并且自动维护这个顺序。
    ----保证有足够的空间来创建聚簇索引。
  • 复合索引

4.索引实现方式

  • B+树:一般比较矮胖,ORACLE默认索引是B+树。范围查询只能用这个。

问题:B树和B+树有什么区别?为什么索引不用B树?
答:B+树在非叶子结点不保存数据,只在叶子结点保存。而B树在叶子结点和非叶子结点都会保存。这种结构导致你如果用B树来进行查询,会增加磁盘IO的次数,导致性能不如B+树。

  • 散列索引:通过散列函数来定位,根据对应键的散列码来查找的一种索引。二级辅助索引。
  • 位图索引:针对多个字段的同时简单查询,只适用于字段值固定并且值种类少的情况。
  • HASH索引

a.根据索引的键值计算出响应的hash值,然后根据hash表中的地址来定位数据。
b.其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash索引的查询效率要远高于 B-Tree 索引
c.只有Memory存储引擎显示支持hash索引

1.优点:检索效率非常高,索引的检索可以一次定位
2.缺点:

  • (1)Hash 索引仅仅能满足"=",“IN"和”<=>"查询,不能使用范围查询。
    由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash
    值的大小关系,并不能保证和Hash运算前完全一样。
  • (2)Hash 索引无法被用来避免数据的排序操作。
    由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算。
  • (3)Hash 索引不能利用部分索引键查询。
    对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
  • (4)Hash 索引在任何时候都不能避免表扫描。
    Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash
    索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
  • (5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
    对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

5.索引设置的规则
1)应该创建索引的列

  • 经常搜索的列、主键的列、连接的列、根据范围进行搜索的列、需要排序的列上、使用在WHERE子句中的列上。

2)不应该创建索引的列

  • 1.在查询中很少使用或者参考的列不应该创建索引。
  • 2.只有很少数据值的列也不应该增加索引。
  • 3.对于那些定义为text, image和bit数据类型的列不应该增加索引。
  • 4.当修改性能远远大于检索性能时,不应该创建索引。

6.索引失效

  • 如果条件中有or。注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引。
  • 对于多列索引,不是使用的第一部分,则不会使用索引(即不符合最左前缀原则)
  • like查询是以%开头
  • 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
  • 如果mysql估计使用全表扫描要比使用索引快,则不使用索引

7.最左前缀原则
多列索引(联合索引)有最左前缀的原则,即最左优先。

发布了60 篇原创文章 · 获赞 55 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/MARY197011111/article/details/87795699
今日推荐