mysql随机查询数据的2个解决方案

emmmm,最近又写前端又写后端,有点忙,好久没写博客,今天来更新一波。

需求:根据商城展示的商品,从数据库中随机查询出相同种类的商品30个,作为随机推介给用户。首先来认识两句sql:

SELECT FLOOR(RAND()*100)
  • 这句sql会返回从0到100的随机数一个,floor的作用是返回舍弃小数点的整数,比如4.5则返回4,相对的是ceil,4.5则返回5。
SELECT * FROM tablename ORDER BY RAND() LIMIT 1
  • 这句sql可能是百度上教你最多的,也是官方的标准sql语句,rand()就是mysql的随机返回函数。

看完上面,你是不是觉得好像有了2就完事了,没必要写这篇博客了呢?确实,我一开始也是这么写的,贴代码~

SELECT
	* 
FROM
	t_merchandise_info 
WHERE
	goods_type_name = #{typeName}    //如果有种类id,这里用id更好
ORDER BY
	RAND() 
	LIMIT 30;

好啦,写完了,然后页面上一执行…等了一年都没出结果,咋回事?拿去navicat执行看看,然后发现了问题所在!
在这里插入图片描述
测试库中的商品表有10万条数据,然后返回的时间长达13秒,emmmm这也太慢了,后面去百度,mysql官方其实也不推介这个函数,他执行的时候会查询所有的表,然后后面原理很复杂,我们只需要知道直接执行效率极低就行了。从用户的角度显然不可能等你这10几秒呀,行吧,那就优化呗,根据百度提示,试下用上面示例的语句1,然后套子函数试试,然后优化成了这样:

SELECT
	* 
FROM
	`t_merchandise_info` 
WHERE
	id >= (
	SELECT
		floor(
		RAND() * ( SELECT MAX( id ) FROM `t_merchandise_info` ))) 
ORDER BY
	id 
	LIMIT 30;

百度了好多都没有解释,不知道大家是不是都看不太懂为啥外层是"id>=",我这里解释一下:子查询查到一个随机id,然后这个id作为一个坐标轴,如果是>=的话就会从这个id处向右(往大取),连续取30个商品返回,注意是连续取的30个商品,某种程度上其实是一种伪随机。同理,如果改成“<=”,那么就会从这个id处往左连续取30个商品。(这里要求id必须为数字,且sql不太完善,需要把最小值的偏移量去掉,也就是准确算出"rand()"里的范围,因为默认id从1开始,就不细说了)

这样写,貌似就可以了,查询时间只有0.6秒!可是,分类呢?按照要求,我应该还加一个where goods_type_name = #{typeName}的,但是这个限制条件,无论是放在子句里,还是主句里,都不生效,仍然会查询全表。加入种类是“奶粉”,放在子句里,确实会使MAX(id)这个的商品的类目限制为“奶粉”,但也只是这一个品,其他29个品都不受限制。如果放在外面,返回的30个结果里就筛选出了10个“奶粉”品,也不符合要求,那咋办呢?

最终,没想到还是根据sql优化的基本操作来解决了这个问题(大家一定要多了解sql优化呀),就是重新定义一个实体类,只返回你需要的字段,不要返回所有,绕了一圈还是回来了…然后用实体类去接收,速度也还可以接受,这样就可以了。

SELECT
   name, goods_img01,id
FROM
  t_merchandise_info t1 
WHERE
   goods_type_name ='奶粉'
ORDER BY
  RAND()
LIMIT 30;

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
分表是一种常用的数据库优化策略,可以将数据按照某种规则分散到不同的表中,从而降低单张表的数据量和查询复杂度,提高数据库的性能和稳定性。以下是一个基于MySQL的分表方案: 1. 确定分表规则 首先需要确定分表的规则,可以按照时间、地域、业务类型等多个维度进行分表。例如,按照时间分表可以将数据按照年、月、日、小时等时间段进行分表;按照地域分表可以将数据按照国家、省份、城市等地理位置进行分表;按照业务类型分表可以将数据按照产品、订单、用户等进行分表。 2. 创建分表 根据确定的分表规则,创建对应的分表。例如,按照时间分表可以创建类似于表名为“table_202101”、“table_202102”等不同时间段的表;按照地域分表可以创建类似于表名为“table_china”、“table_usa”等不同地理位置的表;按照业务类型分表可以创建类似于表名为“table_product”、“table_order”、“table_user”等不同业务类型的表。 3. 选择合适的分表键 在创建分表时,需要选择合适的分表键。分表键决定了数据在分表时应该被分配到哪个表中。分表键的选择需要考虑到数据的分布情况和查询的频率。例如,按照时间分表时可以选择时间字段作为分表键,按照地域分表时可以选择地理位置字段作为分表键。 4. 管理分表数据 在使用分表后,需要进行分表数据的管理,包括数据的导入、查询、删除、备份等操作。由于数据被分散到不同的表中,需要对分表数据进行整合或者分散查询,可以使用联合查询、视图等技术来实现。在备份分表数据时,需要分别备份每个分表,保证数据的完整性和一致性。 总的来说,分表是一种常用的数据库优化策略,可以帮助提高数据库的性能和稳定性。但是,在使用分表时需要根据具体的业务需求进行规划和设计,合理选择分表规则和分表键,以及进行分表数据的管理和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wuzi9

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值