如何建立复合索引,一般你加在那些字段?

建表:

CREATE TABLE `product_comment` (

  `comment_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '评论ID',

  `product_id` int(10) unsigned NOT NULL COMMENT '商品ID',

  `order_id` bigint(20) unsigned NOT NULL COMMENT '订单ID',

  `customer_id` int(10) unsigned NOT NULL COMMENT '用户ID',

  `title` varchar(50) NOT NULL COMMENT '评论标题',

  `content` varchar(300) NOT NULL COMMENT '评论内容',

  `audit_status` tinyint(4) NOT NULL COMMENT '审核状态:0未审核1已审核',

  `audit_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '评论时间',

  `modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',

  PRIMARY KEY (`comment_id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='商品评论表'

插入数据:

INSERT INTO product_comment(product_id,order_id,customer_id,title,content,audit_status) VALUES(1,108310,1,'鼠标','罗技鼠标不错',0);

INSERT INTO product_comment(product_id,order_id,customer_id,title,content,audit_status) VALUES(2,108311,2,'键盘','小米键盘good',0);

INSERT INTO product_comment(product_id,order_id,customer_id,title,content,audit_status) VALUES(3,108312,3,'U盘','华为U盘不错',0);



 

INSERT INTO product_comment(product_id,order_id,customer_id,title,content,audit_status) VALUES(3,108313,4,'U盘','华为U盘不错2',0);

查询sql:

EXPLAIN

SELECT customer_id,title,content FROM `product_comment` WHERE audit_status=0 AND product_id=3 LIMIT 0,3;

没加索引之前见上面图片,问题是加复合索引的话,audit_status 和 product_id 那个放在最左边??

参考58同城30条军规:

如何区分最佳做前缀位置

SELECT COUNT(DISTINCT audit_status)/COUNT() AS audit_statusRate,
COUNT(DISTINCT product_id)/COUNT() AS product_itRate
FROM product_comment

那个字段越接近于1,那个就是区分度更好的,就放在最左边。

-- 建索引
CREATE INDEX idx_product_id_audit_status ON product_comment(product_id,audit_status)
--删索引
DROP INDEX idx_product_id_audit_status ON product_comment
### 数据字段索引后模糊查询失效的原因 当对数据字段添加索引后,`LIKE` 模糊查询仍可能失效的主要原因在于 `LIKE` 的模式匹配方式以及 MySQL 查询优化器的行为。以下是具体分析: #### 1. **前缀通配符的影响** 如果 `LIKE` 条件中的通配符 `%` 出现在字符串开头(例如:`WHERE column LIKE '%abc'`),MySQL 将无法利用 B-Tree 索引来加速查询[^2]。这是因为 B-Tree 索引的设计基于有序性,而前缀通配符使得查询失去了方向性,从而不得不进行全表扫描。 #### 2. **覆盖索引未完全满足需求** 即使存在索引,但如果查询涉及的列未能被索引完全覆盖,则会触发回表操作(即从索引文件跳转至数据文件获取额外信息)。这种情况下,尽管索引部分生效,但由于性能开销较大,MySQL 可能会选择放弃使用索引[^3]。 #### 3. **查询优化器的选择** MySQL 查询优化器可能会评估多种执行计划并选择成本最低的一种。有时,即便有可用索引,优化器也可能判断全表扫描更高效(尤其是在小表或高基数场景下)[^1]。 --- ### 解决方法 针对上述问题,可以通过以下几种方式进行优化: #### 方法一:调整 `LIKE` 表达式的写法 尽可能避免将通配符置于字符串开头。例如,将 `'%abc%'` 改为 `'abc%'` 或者其他可利用索引的形式。对于必须支持任意位置匹配的情况,可以考虑全文索引或其他替代方案。 #### 方法二:创建复合索引 确保索引不仅包含查询条件列,也包含所需返回的结果列,以此实现覆盖索引的效果。这样能够减少甚至消除回表操作带来的性能损耗。 ```sql CREATE INDEX idx_covering ON table_name (column_for_condition, column_to_return); ``` #### 方法三:采用全文索引 对于复杂的文本搜索需求,推荐启用 MyISAM 存储引擎下的 FULLTEXT 索引或者 InnoDB 中的支持功能。相比普通的 B-Tree 索引,FULLTEXT 能够更好地应对复杂模式匹配任务。 ```sql ALTER TABLE table_name ADD FULLTEXT(column_name); SELECT * FROM table_name WHERE MATCH(column_name) AGAINST('search_term'); ``` #### 方法四:借助外部工具 在某些极端情形下,还可以引入 Elasticsearch、Solr 等专门设计用于高级检索的应用程序来增强数据库系统的文本处理能力。 --- ### 总结 通过对 `LIKE` 模糊查询机制的理解及其与不同类型的索引交互关系的认识,可以选择合适的策略提升查询效率。无论是重构 SQL 语句还是重新规划物理存储结构,都需要综合考量业务特点和技术约束因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leighteen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值