能否编写不含WHERE内嵌子查询的SQL语句以优化查询性能?
可行的无IN子查询实现方案
直接通过额外关联一层预过滤的符合条件的套装ID集合,即可替换原WHERE子句中的子查询,和原查询逻辑完全等价,执行效率更高:
SELECT i.nid, GROUP_CONCAT(i.field_prod_in_set_nid SEPARATOR ',') as field_prod_in_set_nid, ad.additional as field_additional_set_prod_nid FROM {content_field_prod_in_set} i -- 关联免费商品汇总表,和原逻辑保持一致 JOIN ( SELECT c.nid, GROUP_CONCAT(c.field_additional_set_prod_nid SEPARATOR ',') as additional FROM {content_field_additional_set_prod} c GROUP BY c.nid ) ad ON ad.nid = i.nid -- 新增关联:预过滤出所有包含购物车商品的套装ID,代替原WHERE子查询 JOIN ( SELECT DISTINCT nid FROM {content_field_prod_in_set} WHERE field_prod_in_set_nid IN ($items_string) ) filter_set ON filter_set.nid = i.nid GROUP BY i.nid
方案说明
- 逻辑完全等价:新增的
filter_set临时表的作用就是筛选出所有包含购物车内商品的套装ID,和原IN子查询的筛选逻辑完全一致,返回结果不会有任何变化 - 性能优势:避免了IN子查询的逐行匹配开销,关联查询更符合数据库的执行优化逻辑,数据量越大性能提升越明显
- 兼容性:支持所有主流SQL数据库,不需要额外修改表结构或业务逻辑
验证结果
当$items_string为45时,filter_set会筛选出nid=67,最终返回结果和你给出的示例完全一致:
| nid | field_prod_in_set_nid | field_additional_set_prod_nid |
|---|---|---|
| 67 | 45,45 | 45 |
内容的提问来源于stack exchange,提问作者qqmisko
相关产品推荐
相关产品推荐

