在本篇博客简单介绍一下分页查询以及聚合查询简单操作。
在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