Environment to prepare
Database version: MySQL 5.7.20-log
Build table SQL
DROP TABLE IF EXISTS `t_ware_sale_statistics`; CREATE TABLE 't_ware_sale_statistics' (' id' bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键 iD ', 'business_id' bigint(20) NOT NULL COMMENT 'bigint ',' ware_inside_code 'bigint(20) NOT NULL COMMENT' bigint ', 'weight_sale_cnt_day' double(16,4) DEFAULT NULL COMMENT ' 'last_thirty_days_sales' double(16,4) DEFAULT NULL COMMENT' last 30 days ', 'last_sixty_days_sales' double(16,4) DEFAULT NULL COMMENT' last 60 days ', 'last_ninety_days_sales' double(16,4) DEFAULT NULL COMMENT' last 90 days ', 'same_period_sale_qty_thirty' double(16,4) DEFAULT NULL COMMENT '2015, 'same_period_sale_qty_sixty' double(16,4) DEFAULT NULL COMMENT '2010 年 60 月 sales ', 'ninety' double(16,4) DEFAULT NULL COMMENT 'ninety ', 'create_user' bigint(20) DEFAULT NULL COMMENT 'create ', 'create_time' datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'create_time ', 'modify_user' bigint(20) DEFAULT NULL COMMENT '主 持 人', 'modify_time' datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ' 'is_delete' tinyint(2) DEFAULT '2' COMMENT 'Whether to delete ', 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=' SQL ';Copy the code
Initialize data
769,063 pieces of data were prepared
Demand background
The same business organization can sell different commodities, and the same commodity can be sold in different business organizations. That is to say, the relationship between business organizations and commodities is many-to-many
Suppose there are n organizations with several products in each organization. How can we find out the sales situation of the products in these stores?
Specifically, something like the following
How to find out the sales situation of commodities 1006, 1008 and 1009 under commodities 1003, 1004 and 100003 under commodities 100001 under 1000, 1001, 1003 and 100002
It is equivalent to a query of a two-tier list (a list of goods in a list of business organizations); Business organization lists and product lists are not fixed, but dynamic
So the question is: how to query the sales situation of certain goods in multiple business organizations
The problem by my description, may be more vague, we understand the meaning of good!
Cyclic query
This is easy to think of, loop the list of business organizations at the code level, and check the database once for each business organization, pseudo code is as follows:
The specific SQL is similar to the following
SQL can walk index
Easy to implement, easy to understand, SQL can also go to the index, everything seems perfect
However, the reality is: the department development specification constraints, can not loop through the database
Oh huo, this way can only give up, find another way
The OR joining together
Through the dynamic SQL function of MyBatis, SQL splicing is similar to the following
The specific SQL is similar to the following
SQL can also walk indexes
Simple implementation, or understand, SQL can also go to the index, and only query the database once, seems feasible
The only pity is: it is a bit of a fee OR, if the business organization is more, that SQL will be longer
As one of the candidates, let’s move on
Mixed check filter
Also using Mybatis dynamic SQL, put business_id list together, ware_inside_code together, similar to the following
The specific SQL is similar to the following
SQL can also walk indexes
The implementation is simple, easy to understand, SQL can also go to the index, and only query the database once, seems feasible
But: the result set found is greater than or equal to the result set we want, you taste, you fine taste!
Therefore, we also need to filter the result set we find, and filter out the result set we want
As a candidate, let’s move on
Okay to compare
The row-to-row comparison feature was added to SQL-92, so that the arguments to compare the =, <, >, and IN predicates are no longer just scalar values, but lists of values
Of course, you still need to use Mybatis dynamic SQL, similar to the following
The specific SQL is similar to the following
SQL can also move indexes
Simple implementation, SQL can also go index, and only query a database, feel feasible
It’s just: it’s a little hard to understand, because we don’t use it so much, so it seems strange
In addition, row comparison is an SQL specification, not a relational database specification, which means that relational databases should support this writing
conclusion
1. Finally, the line comparison method is selected to realize the requirements
Don’t ask me why. To ask is to go!
2. There are many ways to realize a requirement. We need to take the business and various constraints into consideration and choose the most appropriate one
3. Line comparison is introduced in SQL-92, a specification developed in 1992
Line comparison is not a new feature, but an old foundational feature!
reference
-
SQL Advanced Tutorial
-
Magical SQL MySQL execution plan → EXPLAIN, let us understand the execution process of SQL!
-
Magic SQL performance optimization – Let SQL fly
-
Magic SQL pass by → Really use index