英文博客伪原创(如何查询多个业务机构下,SQL也能走索引?)
优采云 发布时间: 2022-01-16 09:23英文博客伪原创(如何查询多个业务机构下,SQL也能走索引?)
环境准备
数据库版本:MySQL 5.7.20-log
创建表 SQL
<p>DROP TABLE IF EXISTS `t_ware_sale_statistics`;
CREATE TABLE `t_ware_sale_statistics` (
`id` bigint(20) NOT AUTO_INCREMENT COMMENT '主键id',
`business_id` bigint(20) NOT COMMENT '业务机构编码',
`ware_inside_code` bigint(20) NOT COMMENT '商品自编码',
`weight_sale_cnt_day` double(16,4) DEFAULT COMMENT '平均日销量',
`last_thirty_days_sales` double(16,4) DEFAULT COMMENT '最近30天销量',
`last_sixty_days_sales` double(16,4) DEFAULT COMMENT '最近60天销量',
`last_ninety_days_sales` double(16,4) DEFAULT COMMENT '最近90天销量',
`same_period_sale_qty_thirty` double(16,4) DEFAULT COMMENT '去年同期30天销量',
`same_period_sale_qty_sixty` double(16,4) DEFAULT COMMENT '去年同期60天销量',
`same_period_sale_qty_ninety` double(16,4) DEFAULT COMMENT '去年同期90天销量',
`create_user` bigint(20) DEFAULT COMMENT '创建人',
`create_time` datetime NOT DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`modify_user` bigint(20) DEFAULT COMMENT '最终修改人',
`modify_time` datetime NOT DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最终修改时间',
`is_delete` tinyint(2) DEFAULT '2' COMMENT '是否删除,1:是,2:否',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_business_ware` (`business_id`,`ware_inside_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='商品销售统计';</p>
初始化数据,准备769063条数据
需求背景
商品在商业组织下销售。同一个商业机构可以销售不同的产品,同一种产品可以在不同的商业机构销售。也就是说:业务组织和产品是多对多的关系。
假设现在有n个机构,每个机构有几种产品,如何查询各个产品在这些店铺的销售情况?
具体来说,它类似于以下内容:
100001下的产品1000、1001、1003、100002下的产品1003、1004和100003、1006、1008、的销量如何查询1009
相当于查询一个双层列表(业务组织列表中的一组商品列表);企业组织清单和商品清单都不是固定的,而是动态的
那么问题来了:如何查询多个业务机构下某些商品的销售额
(我一描述问题,可能就比较暧昧了,大家明白意思就好!)
循环查询
很容易想到这一点。业务机构列表在代码级别循环,每个业务机构检查一次数据库。伪代码如下:
具体SQL类似如下
SQL可以走索引
实现简单易懂,SQL也可以索引,一切看起来都很完美
然而现实是:部门制定规范约束,无法循环检查数据库
唉,只能放弃这条路,另谋出路。
或拼接
通过MyBatis的动态SQL功能,进行SQL拼接,类似如下
具体SQL类似如下
SQL也可以去索引
实现简单易懂。SQL也可以索引,数据库只查询一次,看起来可行
唯一遗憾的是:有点OR,如果业务组织多,SQL会更长
作为候选人之一,我们往下看
混合检查过滤器
同样是使用Mybatis的动态SQL将business_id列表和ware_inside_code放在一起,类似如下
具体SQL类似如下
SQL也可以去索引
实现简单易懂。SQL也可以索引,数据库只查询一次,看起来可行
但是:找到的结果集大于等于我们要的结果集,你尝尝,你就没事!
因此,我们还需要对找到的结果集进行一次过滤,以过滤掉我们想要的结果集。
也让我们成为候选人之一,让我们继续往下看
逐行比较
在 SQL-92 中,增加了行到行比较的功能,使得比较谓词 = 、 、 IN 谓词的参数不再只是标量值,还可以是值的列表
当然,还是要使用Mybatis的动态SQL,类似如下
具体SQL类似如下
SQL也可以通过索引
实现简单,SQL也可以索引,数据库只查询一次,感觉可行
只是:有点难理解,因为我们不经常用,所以这种写法好像很陌生
另外,逐行比较是SQL规范,不是关系数据库规范,也就是说所有的关系数据库都应该支持这种写法。
总结
1. 最后还是选择了逐行对比的方式来实现需求。不要问我为什么,只要问我高!
2. 通常有很多方法可以实现某个需求。我们需要考虑业务和各种约束来选择最合适的一种。
3. SQL-92 中引入了逐行比较。SQL-92 是 1992 年制定的规范。逐行比较不是新特性,而是早已存在的基本功能!
本文链接:/youzhibing/p/15101096.html
#投稿渠道#
让更多人看到你的博客
如果你有在CSDN、博客园、掘金等平台写技术博客的习惯,希望你的原创博客被更多人看到,可以来Java后台投稿。
Java 后端鼓励读者贡献个人技术博客、面试经验和教程。无论是入门图文教程还是通俗技术讲解,只要你喜欢写,我们都欢迎你投稿。
稿件基本要求:
• 文章确实是个人作品原创,如果在其他非公开渠道发表过,只要是个人原创。
• 稿件建议以markdown格式书写,并附图片作为附件发送。要求图片清晰,句子流畅。
• 如被录用原创稿件,我们将提供稿件费和个人影响力曝光,稿件费将根据文章的阅读量和质量确定。
投稿渠道:
• 投稿请联系下方微信,备注:原创投稿
△长按添加Java后端编辑器