首页 > 数据库 >数据库学习笔记(三)—— MySQL 之 SELECT(查询)篇

数据库学习笔记(三)—— MySQL 之 SELECT(查询)篇

时间:2024-01-22 19:13:39浏览次数:37  
标签:数据库 查询 索引 select SELECT MySQL where 字段名

查询


单表查询

select 分组函数,分组后的字段
from 表名
[where 条件]
[group by 分组的字段]
[having 分组后的筛选]
[order by 排序列表];

排序

SELECT 字段名 FROM 表名 ORDER BY 字段名 [ASC | DESC];
  • ASC 表示升序,DESC 表示降序,而 ORDER BY 默认值为 ASC。

多字段排序:

 

 常用聚合函数

函数名描述
COUNT() 返回参数字段的数量,不统计为NULL的记录
SUM() 返回参数字段之和
AVG() 返回参数字段的平均值
MAX() 返回参数字段的最大值
MIN() 返回参数字段的最小值
GROUP_CONCAT() 返回符合条件的参数字段值的连接字符串
JSON_ARRAYAGG() 将符合条件的参数字段值作为单个JSON数组返回,MySQL5.7.22新增
JSON_OBJECTAGG() 将符合条件的参数字段值作为单个JSON对象返回,MySQL5.7.22新增

 

分组统计

SELECT 字段名 FROM 表名 [WHERE 条件表达式] GROUP BY 字段名 [with rollup];
  • with rollup 作用是求和

 ( select prices,count(name) from goods group by prices with rollup; 的作用是对价格分组,查询分组后的价格 和 每种价格的商品名个数,还有总和)

统计筛选

当对查询的数据执行分组操作时,可以利用 HAVING 根据条件进行数据筛选,与WHERE功能相同,但是在实际运用时两者有一定的区别。

  • WHERE 操作是从数据表中获取数据,将数据从磁盘存储到内存中,而 HAVING 是对已存放到内存中的数据进行操作。
  • HAVING 位于GROUP BY 子句后,而 WHERE 位于 GROUP BY 子句之前。
  • HAVING 关键字后可以使用聚合函数,而 WHERE 则不可以。通常情况下,HAVING 关键字与GROUP BY 一起使用,对分组后的结果进行过滤。

 

查询限制

select 字段名 from 表名 ... limit [偏移,]限制数;
  • 限制数 限定每次获取最多记录数量
  • 偏移 表示从哪条记录开始查询

 

多表查询

联合查询

SELECT 字段名 FROM 表一 ……  UNION SELECT 字段名 FROM 表二 ……;
  • 相当于求并集
  • 默认去重,可以将 UNION 换为 UNION ALL 来取消去重
  • 用 IN 可以求交集
  • 用 NOT IN 可以求差集

(这个例子不太好)

用 IN 求交集:

(这其实是子查询的例子)

使用 NOT IN 求差集:

 

连接查询

 新建一张表来演示:

交叉查询

将两张表的全部记录交叉组合,通过使用集合运算符GROSS JOIN(笛卡尔积)来完成

SELECT 字段名 FROM 表1 CROSS JOIN 表2 ;
-- 或者
SELECT 字段名 FROM 表1 , 表2 ;
例如,A={a,b}, B={0,1,2},则 A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)} B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}

 

内连接查询

内连接查询根据连接条件可以对交叉连接查询的部分结果进行筛选,仅筛选出两张表中相互匹配的记录。

SELECT 字段名 FROM 表1 [ INNER ] JOIN 表2 ON 匹配条件 ;

 

外连接查询

  • 左外连接

左外连接会输出 左表的全部记录 和 右表满足条件的记录:

SELECT 字段名 FROM 表1 LEFT JOIN 表2 ON 匹配条件 ;

 

 

  • 右外连接

左外连接会输出 右表的全部记录 和 左表满足条件的记录:

SELECT 字段名 FROM 表1 RIGHT JOIN 表2 ON 匹配条件 ;

 

  • 全连接

MySQL不支持全连接,但可以通过 UNION 将 左连接 和 右连接 联合起来实现全连接:

 

子查询

 也可以称为嵌套查询,是一种嵌套在其它SQL查询的Where子句中的查询

  • 子查询必须包含在()内
  • 子查询不可以直接应用在聚合函数中,子查询也无法使用 ORDER BY
  • Ntext、text、image 数据类型不可以在子查询的选择列表中使用
  • 子查询外部可以是 INSERT / UPDATE / DELETE / SELECT 的任何一个
  • 关键字 DISTINCT 不能与包含 GROUP BY 的子查询一起使用

常用操作符:

  • IN           指定的集合范围内多选一
  • NOT IN 不在指定的集合范围之内
  • ANY       子查询返回列表中,有任意一个满足即可
  • SOME     等同于ANY
  • ALL         子查询返回列表的所有值都必须满足
  • 用法在联合查询的例子中有出现

 (查询 比小李和小明销售额高 的记录)

  1. 先分组统计
  2. 然后执行 having 条件内部的 select,得到小李和小明的销售额
  3. 条件是 销售额 大于 子查询得到所有销售额
  4. 结果就只有小张
  5. 使用 having 而不用 where,是因为用到了聚合函数

EXISTS 和 NOT EXISTS

  • EXISTS 用于检查子查询是否至少会返回一行数据;如果该子查询至少返回了一行数据,则为 True;如果子查询没有返回数据,则为 False,某些情况下,也可以使用 IN 或者 ANY 字段来代替。
  • NOT EXISTS 与 EXIST 相反

 

查询优化

索引是对查询性能优化最有效的手段

索引优化

 索引添加

在创表的同时添加索引就不再赘述,这里讲一下如何在已建表种添加索引

alter table 表名 add 索引类型 索引名(字段名,字段名...);
create 索引类型 索引名 on 表名(字段名,字段名...);

索引类型:

  • index
  • unique index
  • fulltext

索引覆盖

我们知道除了主键索引,其他的都是辅助索引,辅助索引检索会发生回表。

但有一种情况不会发生回表,那就是索引覆盖。

索引覆盖是指 查询的数据在索引中就取得了,即覆盖,那就不需要回表查询。

举个例子:

select id,age from person where age=16;

  从上图中可以看到,我们想要查询的 id 和 age,在辅助索引中就已经全部得到了,这时候就不用回表查询了。

 

最左匹配原则

  • 最左匹配原则是指索引以最左边的为起点,任何连续的索引都能匹配上,在联合索引中才用的上。
  • 当遇到范围查询 (>、<、between、like) 就会停止匹配。

假如我们建立了一个联合索引:

CREATE INDEX INDEX_abc ON test(a,b,c);

通过以下例子理解什么是最左匹配原则:

select * from test where a=1; // 只使用索引 a
 
select * from test where b=2; // 不使用索引
 
select * from test where c=3; // 不使用索引
 
select * from test where a=1 and b=2; // 只使用索引 a,b
 
select * from test where a=1 and c=3; // 只是用索引 a
 
select * from test where b=2 and a=1; // 只使用索引 a,b,mysql有查询优化器
 
select * from test where a=1 and b=2 and c=3; // 使用索引 a,b,c
 
select * from test where a=1 and b>2 and c=3; // 只使用索引 a,b

 

索引下推

  索引下推是 MySQL 5.6 及以上版本上推出的,用于对查询进行优化。在查询非聚簇索时,拿到了叶子结点的聚簇索引,然后对聚簇索引中包含的字段先做判断,直接过滤掉不满足条件的记录,从而减少回表次数。

以 user 表中的联合索引(name,age)为例:

select * from user where name='张%' and age='10';
 
-- 表中有四条数据
-- 1  张三  10
-- 2  张四  11
-- 3  张五  12
-- 4  老六  13

MySQL 5.6 之前没有索引下推,它的执行流程如下:

  • 在非聚簇索引中根据 name='张%' 查到聚簇索引中匹配的 id

  • 使用匹配的 id 进行回表查询

(索引 age 没用上)

MySQl 5.6 之后引入索引下推,它会根据 name='张%' 和 age 一起过滤数据:

 索引设计原则

  • 单表索引建议控制在5个以内
  • 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引
  • 使用短索引
  • 如果有order by、group by的场景,利用索引的有序性
  • 索引不会包含有NULL值的列,IS NULL,IS NOT NULL无法使用索引
  • 利用覆盖索引来进行查询操作,避免回表,减少select * 的使用
  • 更新十分频繁、数据区分度不高的列不宜建立索引
  • 强制类型转换会全表扫描
  • 不要在索引列上面做任何操作(计算、函数),否则会导致索引失效而转向全表扫描
  • union、in、or 都能够命中索引,建议使用 in
  • like语句的前导模糊查询不能使用索引

 

表结构优化

  • 对于需要经常联合查询的表,可以建立中间表以提高查询效率
  • 关联操作设计的表不要太多,否则执行会很慢
  • 表设计不能有太多的列,数千的列会影响性能
  • 合理应用三大范式,有利于提高查询效率

三大范式 

第一范式(1NF):用来确保每列的原子性,要求每列(或者每个属性值)都是不可再分的最小数据单元(也称为最小的原子单元)。

第二范式(2NF):如果一个表满足第一范式,并且除了主键以外的其他列全部都依赖于该主键,那么该表满足第二范式。

第三范式(3NF):如果一个关系满足第二范式,并且除了主键以外的其他列都依赖于主键列,列和列之间不存在相互依赖关系,则满足第三范式。

 

SQL语句优化

  • 避免 SELECT *,只查询需要的字段
  • 一般情况下不推荐使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引,而like “aaa%”可以使用索引
  • 尽量使用连接代替子查询,因为使用 join 时,MySQL 不会在内存中创建临时表
  • or 查询改写成 union 查询
  • 查询语句尽可能简单,大语句拆小语句,减少锁时间
  • 尽量避免大事务操作,提高系统并发能力

标签:数据库,查询,索引,select,SELECT,MySQL,where,字段名
From: https://www.cnblogs.com/Owhy/p/17965144

相关文章

  • openGauss学习笔记-204 openGauss 数据库运维-常见故障定位案例-重建索引失败
    openGauss学习笔记-204openGauss数据库运维-常见故障定位案例-重建索引失败204.1重建索引失败204.1.1问题现象当Desc表的索引出现损坏时,无法进行一系列操作,可能的报错信息如下。index\"%s\"containscorruptedpageatblock%u",RelationGetRelationName(rel),BufferG......
  • 【数据库】Navicat Premium历史版本下载
    ✨官方下载链接访问如下链接一般下载到的是当前大版本号下的最新版本NavicatPremium15#Windowshttp://download.navicat.com/download/navicat150_premium_cs_x64.exe#macOShttp://download.navicat.com/download/navicat150_premium_cs.dmgNavicatPremium16#Wi......
  • mysql8.0主从不一致,重新同步从库
    背景:线上宕机,导致数据不一致,当时为了快速恢复业务,仅使用主库,现在需要恢复,因为主从数据相差比较大,所以对从库重新进行同步。1、首先重置从库的同步设置、并清除从库不一致数据1)#停止slavestopslave;#重置slave,会重置从库相关设置。resetslaveall;2)#清除已同步......
  • liunx上面备份postgres数据库脚本
    背景在liunx上面安装docker,在docker容器中安装postgres数据库,一定的时间进行数据库的备份 1安装postgresql客户端安装客户端可以执行pg_dump命令sudoyuminstallpostgresql删除客户点sudoyumremovepostgresql2.创建.sh文件#!/bin/bashecho"开始执行Postgr......
  • 数据库机器迁移对AlwaysON 集群影响测试
    1主3从(共享文件见证)  模拟事故AlwaysON集群结论主域控服务器重启共享文件夹见证失败,SQL集群无影响无影响修改共享文件夹见证路径第一次测试修改后:整个集群突然重启,查询下来不确认是否为修改路径有关,      第二次测试修改后:原有见证路径变成脱机,新路径联机,但集群线上的还是......
  • MySQL修改完my.ini无法启动
    背景在安装完mysql后查看my.ini文件,发现default-character-set和character-set-server的值都是空的,想着都设置成utf8,没想到改完保存后mysql的服务就无法启动了解决方法:1、修改ANSI编码在网上找了一圈,发现可能是因为我用默认的记事本修改后,编码给改成了UTF-8的,需要使用另存......
  • select count(*) 引发的思考
    1、属性上添加注解:@JsonIgnoreimportcom.fasterxml.jackson.annotation.JsonIgnore;@JsonIgnore@ApiModelProperty("属性")privateLongsqlTotal;privateinttotal;针对Long类型,接口返回时,会转化为字符串,这样做是因为怕前端解析时出现精度问题......
  • windows dos 脚本(mysql)自动备份
    @echooff::以下1~8参数请按自己的情况修改;其他的不需要修改::=======================视各环境情况修改=================::1,备份目标主机setdbhost=127.0.0.1::2,数据库端口setdbport=3306::3,本地MYSQL的bin路径setmysqlbin="C:\ProgramFiles\MySQL\MySQLServe......
  • MySQL回表查询与索引覆盖
    前言  InnoDB引擎中,B+树索引可以分为聚簇索引和辅助索引两大类。在介绍“回表”和“索引覆盖”之前,我们先来了解一下这两个概念。聚簇索引  聚簇索引也叫聚集索引,它并不是一种单独的索引类型,在聚簇索引的叶子页中,保存了整张表的行数据信息,所以也将聚簇索引的叶子节点......
  • ETLCloud:实现数据库快速输入输出的利器
    在当今大数据时代,数据的高效处理和管理成为企业发展的关键。而数据库作为数据存储和管理的核心,其输入输出效率的提升对于企业来说至关重要。ETLCloud数据集成工具,为企业提供了快速、灵活、稳定的数据库输入输出解决方案,极大地简化了数据处理流程,提高了工作效率。 系统优点简......