MySQL 数据库 分页查询/聚合查询

引言

在本篇博客简单介绍一下分页查询以及聚合查询简单操作。

分页查询

在MySQL中,分页查询一般都是使用limit子句实现,limit子句声明如下:

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT子句可以被用于指定 SELECT 语句返回的记录数。需注意以下几点:

1、第一个参数指定第一个返回记录行的偏移量

2、第二个参数指定返回记录行的最大数目

3、如果只给定一个参数:它表示返回最大的记录行数目

4、第二个参数为 -1 表示检索从某一个偏移量到记录集的结束所有的记录行

5、初始记录行的偏移量是0(而不是 1)

下面是一个应用实例:

select * from orders where type=8 limit 1000,10;

该条语句将会从表 orders 中查询第1000条数据之后的10条数据,也就是第1001条到第1010条数据。

数据表中的记录默认使用主键(一般为id)排序,上面的结果相当于:

select * from orders where type=8 order by id limit 10000,10;

使用子查询优化

这种方式先定位偏移位置的 id,然后往后查询,这种方式适用于 id 递增的情况。

select * from orders where type=8 limit 100000,1;

select id from orders where type=8 limit 100000,1;

select * from orders where type=8 and 
id>=(select id from orders where type=8 limit 100000,1) 
limit 100;

select * from orders where type=8 limit 100000,100;

针对上面的查询需要注意:

1、比较第1条语句和第2条语句:使用 select id 代替 select * 速度增加了3倍;
2、比较第2条语句和第3条语句:速度相差几十毫秒;
3、比较第3条语句和第4条语句:得益于 select id 速度增加,第3条语句查询速度增加了3倍,这种方式相较于原始一般的查询方法,将会增快数倍。

使用 id 限定优化

这种方式假设数据表的id是连续递增的,则我们根据查询的页数和查询的记录数可以算出查询的id的范围,可以使用 id between and 来查询:

select * from orders where type=2 
and id between 1000000 and 1000100 limit 100;

还可以有另外一种写法:

select * from orders where id >= 1000001 limit 100;

当然还可以使用 in 的方式来进行查询,这种方式经常用在多表关联的时候进行查询,使用其他表查询的id集合,来进行查询:

select * from orders where id in
(select order_id from trade_2 where goods = 'pen')
limit 100;

这种 in 查询的方式要注意:某些 mysql 版本不支持在 in 子句中使用 limit。

关于数据表的id说明

一般情况下,在数据库中建立表的时候,每一张表强制添加 id 递增字段,这样更方便我们查询数据。

如果数据量很大,比如像订单这类,一般会推荐进行分库分表。这个时候 id 就不建议作为唯一标识了,而应该使用分布式的高并发唯一 id 生成器来生成,并在数据表中使用另外的字段来存储这个唯一标识。

首先使用范围查询定位 id (或者索引),然后再使用索引进行定位数据,即先 select id,然后在 select *;这样查询的速度将会提升好几倍。

聚合查询

也就是组函数,在一个行的集合(一组行)上进行操作,对每个组给一个结果。

常用的组函数:

函数 说明
COUNT 统计行的数量
SUM 计算某一列的合计值,该列必须为数值类型
AVG 计算某一列的平均值,该列必须为数值类型
MAX 计算某一列的最大值
MIN 计算某一列的最小值

1、count函数

count(*):返回表中满足where条件的行的数量

select count(*) from salary_tab where salary='1000';
select count(*) from salary_tab;  #没有条件,默认统计表数据行数

count(列):返回列值非空的行的数量

select count(salary) from salary_tab;

count(distinct 列):返回列值非空的、并且列值不重复的行的数量

select count(distinct salary) from salary_tab;

count(expr):根据表达式统计数据

select UNIT as '单位',
    COUNT(TO_DAYS(DATE)=TO_DAYS(NOW()) or null) as '今日统计',
    COUNT(YEAR(DATE)=YEAR(NOW()) or null) as '今年统计'
    from v_jjd
    group by JJDW;

2、max和min函数—统计列中的最大最小值

select max(salary) from salary_tab;
select min(salary) from salary_tab;

3、sum和avg函数—求和与求平均

select sum(salary) from salary_tab;
select avg(salary) from salary_tab;
select avg(ifnull(salary,0)) from salary_tab;

注意:要想列值为NULL的行也参与组函数的计算,必须使用IFNULL函数对NULL值做转换。

参考

https://m.w3cschool.cn/mysql/mysql-xilz2oy6.html

猜你喜欢

转载自blog.csdn.net/bingfeilongxin/article/details/88393011