电商商品表常见筛选字段包括category_id、status、price、score、sales_count、created_at等,复合索引应按“等值字段(category_id、status)→范围字段(price、score)→排序字段(sales_count)”顺序设计,遵循最左前缀原则并避免范围查询中断后续列使用。

商品表常见筛选字段有哪些
电商商品筛选通常涉及多条件组合,比如 category_id、status、price、score(评分)、sales_count(销量)、created_at(上架时间)等。用户可能查“手机类目下价格 1000–3000、评分 ≥4.5、已上架的商品”,SQL 类似:
SELECT * FROM products WHERE category_id = 1024 AND status = 1 AND price BETWEEN 1000 AND 3000 AND score >= 4.5 ORDER BY sales_count DESC LIMIT 20;
这类查询的性能瓶颈往往不在计算,而在数据定位——索引设计是否覆盖了 WHERE + ORDER BY 的关键路径。
复合索引顺序怎么排
MySQL 的 B+ 树索引是有序结构,索引字段顺序直接影响能否命中和利用程度。原则是:等值查询字段在前,范围查询字段居中,排序字段尽量靠后且避免混合方向。
-
category_id和status是高频等值条件,适合放最左 -
price和score是范围条件,只能放在等值之后,且其中最多一个能用于索引“截断”(后续字段失效) -
sales_count是 ORDER BY 字段,如果写在索引末尾且无方向冲突(如只用DESC),可避免文件排序(Using filesort)
推荐索引:INDEX idx_cat_status_price_score_sales (category_id, status, price, score, sales_count)
注意:
- 不要把
score放price前面,否则price BETWEEN就会截断索引,导致score和sales_count无法使用 - 如果查询中有时按
created_at DESC排序,而有时按sales_count DESC,不要强行塞进同一索引——优先保障高频排序字段,低频的另建索引或接受Using filesort
为什么不能给每个字段都单独建索引
单列索引在多条件查询中效果有限。例如:
- 单独
INDEX(category_id)+INDEX(status),MySQL 通常只会选其一(成本更低的那个),其余条件靠全表扫描过滤 - 优化器不擅长合并多个单列索引做 AND 查询(除非是主键或唯一索引,且满足 index merge 条件,但实际极少触发且性能不稳定)
更麻烦的是:
- 每个额外索引都会拖慢 INSERT/UPDATE/DELETE 速度,并占用磁盘和内存
- 索引越多,buffer pool 压力越大,可能挤出热数据
所以宁可花时间分析真实慢查询的 EXPLAIN 输出,也不盲目堆索引。
如何验证索引是否生效
别依赖“建了就等于用了”。执行 EXPLAIN FORMAT=TRADITIONAL 看关键指标:
-
type应为range或ref(不是ALL或index) -
key显示实际使用的索引名 -
key_len能反映用了索引的前几列(例如索引共 5 列,key_len只有前 3 列的字节数,说明第 4 列开始没用上) -
Extra中不能有Using filesort或Using temporary(除非必要聚合)
特别注意:
- 如果 WHERE 中用了函数或表达式,比如
WHERE YEAR(created_at) = 2024,索引直接失效 -
LIKE开头带通配符(LIKE '%手机')也无法走索引,要改用全文索引或倒排表
索引不是一劳永逸的配置项,它随查询模式变化而迅速过时。上线后必须结合慢日志和 performance_schema 定期回检,而不是等用户投诉才想起看 EXPLAIN。


















