指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub

mysql之同一个字段做交集查询优化: 最近做了一个这样的需求,对同一个字段做条件筛选,开始比较纠结,怎么做效率更高,主要有如下两种方案:

通过多个 exists对同一个字段(这里正好是等值查询)做交集查询:
SELECT `id`,`name`,`cover_image`,`price`,`score`,`remark`,`brand`,`subclass`,`category_one`,`category_two`,`detail` FROM `d_products` WHERE (kind = '养老服务' and (name like '%水%' or detail like '%水%')) AND (EXISTS(SELECT id FROM d_product_attributes WHERE `d_product_attributes`.`product_id`  = `d_products`.`id` AND `d_product_attributes`.`attribute_value` = '卫浴') and EXISTS(SELECT id FROM d_product_attributes WHERE `d_product_attributes`.`product_id`  = `d_products`.`id` AND `d_product_attributes`.`attribute_value` = '介护老人') and EXISTS(SELECT id FROM d_product_attributes WHERE `d_product_attributes`.`product_id`  = `d_products`.`id` AND `d_product_attributes`.`attribute_value` = '防滑')) ORDER BY id desc LIMIT 10;


explain结果:
explain结果:
id   | select_type          | table                   | partitions    | type | possible_keys           |  key                 | key_len | ref  | rows | filtered | Extra
1	   PRIMARY	            d_japan_products		                    ref	    index_kind	            index_kind	            768	     const	 1276	20.99	Using where
3	  DEPENDENT SUBQUERY	d_japan_product_attributes		            ref	    attribute_value-index	attribute_value-index	768	     const	 669	10	    Using where
2	  DEPENDENT SUBQUERY	d_japan_product_attributes		            ref	    attribute_value-index	attribute_value-index	768	     const	 538	10	    Using where



通过单个exists 配合 or 范围查询实现:
SELECT `id`,`name`,`cover_image`,`price`,`score`,`remark`,`brand`,`subclass`,`category_one`,`category_two`,`detail` FROM `d_products` WHERE (kind = '养老服务' and (name like '%水%' or detail like '%水%')) AND (EXISTS(SELECT count(id) as id_count FROM `d_product_attributes` WHERE `d_product_attributes`.`product_id` = `d_products`.`id` AND (`d_product_attributes`.`attribute_value` = '卫浴' or `d_product_attributes`.`attribute_value` = '介护老人') group by `d_product_attributes`.`product_id` HAVING id_count = 2)) ORDER BY id desc LIMIT 10;


explain结果:
id   | select_type          | table                   | partitions    | type | possible_keys           |  key                 | key_len | ref  | rows | filtered | Extra
1	   PRIMARY	            d_japan_products		                   ref	    index_kind	            index_kind	            768	     const	1276	20.99	Using where
2	   DEPENDENT SUBQUERY	d_japan_product_attributes		           range	attribute_value-index	attribute_value-index	768		        1207	10	    Using index condition; Using where; Using temporary; Using filesort


总结:对比可以知道,通过第一种方式查询的更快一些,原因是 第一种 会用到等值查询配合 attribute_value 字段上的索引会非常快,一个 type 是 ref,另一个 type 是 range