mysql添加索引反而速度变慢

本文探讨了导致数据库索引失效的几种情况,包括使用'in'、'not in'操作符,OR条件下的索引选择,非最左前缀索引,LIKE模糊匹配百分号使用,函数和表达式计算,以及字段类型不匹配等。了解这些情况有助于优化数据库查询性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

索引失效几种情况

1.使用in、not in,会导致索引失效

失效的原因和 Mysql 的版本以及表中的数据量有关系,在 8.0 之后的版本是走索引的

2.or 分割的条件,如果 or 左边的条件存在索引,而右边的条件没有索引,不走索引

因为 OR 的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此索引的条件列也会失效。

3.索引字段不是联合索引字段的最左字段

4.like 使用了 ‘%’模糊匹配

5.被索引字段使用了内置函数

使用了SUM(), MIN(), MAX(), COUNT(), and so forth

6.被索引字段使用了表达式计算

7.字段类型不匹配导致的索引失效

<think>嗯,用户问的是MySQL如何对索引进行优化。首先,我需要回忆一下索引优化的各种方法。索引优化是数据库性能调优的重要部分,正确的索引可以显著提升查询速度,但设计不当的索引反而会影响性能。 首先,应该考虑选择合适的索引类型。比如,B-Tree索引适用于大多数情况,尤其是范围查询。而全文索引适用于文本搜索,空间索引处理地理数据,哈希索引则适合等值查询。用户可能需要根据不同的场景选择合适的类型。 接下来,覆盖索引的概念很重要。如果查询只需要索引中的字段,就可以避免回表,减少I/O操作。比如SELECT id, name FROM users WHERE age=25,如果索引包含(age, name, id),就能直接使用索引返回结果,不需要访问数据行。 索引列的顺序也很关键,最左前缀原则决定了索引的使用情况。比如复合索引(a,b,c),查询条件中必须包含a才能有效使用这个索引。如果用户经常用a和b作为条件,那么索引的顺序应该按查询频率和选择性来排列,选择性高的列放在前面可能更好。 避免冗余索引也很重要,比如已经有了(a,b)索引,再创建(a)就是多余的,因为最左前缀已经覆盖了。需要检查现有索引是否有重叠,删除不必要的可以减少存储和维护开销。 索引选择性是指索引列不同值的比例,高选择性的列(比如唯一ID)更适合作为索引。低选择性的列(比如性别)建立索引效果不大,可能全表扫描更快。这里可能需要用计算公式:选择性=不同值的数量/总行数,值越高越好。 还有,对于长字符串列使用前缀索引,可以减少索引大小,提升效率。比如ALTER TABLE users ADD INDEX idx_name(name(10)),只索引前10个字符。不过需要平衡前缀长度和选择性,避免重复太多。 另外,索引下推是MySQL5.6后的优化,可以在存储引擎层过滤数据,减少回表次数。比如WHERE a=1 AND b=2,索引是(a,b),存储引擎会直接过滤a和b,而不是先回表再过滤。 定期分析慢查询日志,找出执行效率低的SQL,用EXPLAIN分析执行计划,查看是否用到了合适的索引。如果发现全表扫描或者临时表,可能需要增或调整索引。 还有,索引列不要参与运算或函数,否则无法使用索引。比如WHERE YEAR(create_time)=2023应该改为范围查询,而不是使用函数。 对于排序和分组操作,如果ORDER BY或GROUP BY的列有索引,可以避免filesort。需要确保排序顺序和索引一致,或者考虑覆盖索引。 主键索引使用自增ID可以避免页分裂,提升写入性能。而UUID这类随机值会导致插入效率下降,因为数据页需要频繁调整。 最后,定期维护索引,删除未使用的,重建碎片化的索引,比如使用OPTIMIZE TABLE。同时监控索引的使用情况,通过performance_schema或SHOW INDEX来查看索引的选择性和使用频率。 总结的时候,可能需要分点列出,结构清晰,让用户容易理解。还要注意用户可能遇到的常见问题,比如索引失效的情况,如何选择复合索引的顺序,如何分析慢查询等。可能用户的实际场景中有不同的数据量和查询模式,需要根据具体情况调整优化策略。比如OLTP系统和高并发的写入,可能需要更谨慎地添加索引,避免写操作变慢。而读多写少的系统可以适当增索引提升查询速度。</think>MySQL索引优化是提升查询性能的关键手段,需结合数据结构、查询模式和索引特性进行综合设计。以下是分步骤的优化策略: --- ### 一、索引设计原则 1. **选择合适索引类型** - **B-Tree索引**:默认类型,支持范围查询(`>`、`<`、`BETWEEN`)和排序。 - **全文索引(FULLTEXT)**:针对文本内容的模糊查询(`MATCH...AGAINST`)。 - **哈希索引**:仅支持等值查询(`=`),内存表默认索引。 - **空间索引(SPATIAL)**:地理数据查询。 2. **覆盖索引(Covering Index)** - 索引包含查询所需所有字段时,避免回表操作。 - 示例: ```sql -- 索引 (age, name) SELECT name FROM users WHERE age = 25; ``` --- ### 二、索引优化策略 1. **复合索引的最左前缀原则** - 索引 `(a, b, c)` 可支持 `WHERE a=1`、`WHERE a=1 AND b=2`,但无法支持 `WHERE b=2`。 - **选择性高的列放左侧**:区分度高的列(如用户ID)优先。 2. **避免冗余索引** - 已有 `(a, b)` 时,单独创建 `(a)` 是冗余的。 3. **索引列不参与计算** - **错误写法**:`WHERE YEAR(create_time) = 2023` - **优化写法**:`WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31'` 4. **利用索引下推(Index Condition Pushdown, ICP)** - MySQL 5.6+ 支持,在存储引擎层过滤数据。 ```sql -- 索引 (a, b) SELECT * FROM table WHERE a = 1 AND b > 10; ``` --- ### 三、索引使用监控 1. **通过 `EXPLAIN` 分析执行计划** - 关注 `key`(使用索引)、`rows`(扫描行数)、`Extra`(是否出现 `Using filesort` 或 `Using temporary`)。 2. **慢查询日志分析** - 启用慢查询日志,定位低效SQL: ```sql SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 2; -- 超过2秒的查询 ``` --- ### 四、常见优化场景 1. **排序和分组优化** - 对 `ORDER BY` 或 `GROUP BY` 字段建索引,避免 `filesort`。 - 示例: ```sql -- 索引 (age) SELECT * FROM users ORDER BY age; ``` 2. **前缀索引(Prefix Index)** - 针对长字符串(如VARCHAR(255)),节省存储空间: ```sql ALTER TABLE users ADD INDEX idx_email(email(10)); ``` 3. **索引选择性计算** - 公式:`选择性 = COUNT(DISTINCT column) / COUNT(*)` - 选择性 > 0.1 时适合建索引。 --- ### 五、维护与注意事项 1. **定期重建索引** - 删除碎片化索引: ```sql ALTER TABLE table_name ENGINE=InnoDB; -- 重建表 OPTIMIZE TABLE table_name; -- 优化表 ``` 2. **避免过多索引** - 单表索引数量建议不超过5个,过多索引会降低写入性能。 3. **主键设计** - 使用自增整型主键,避免页分裂。 --- ### 六、示例:复合索引优化 ```sql -- 原始查询(未优化) SELECT * FROM orders WHERE user_id = 100 AND status = 'paid' ORDER BY create_time DESC; -- 优化步骤: -- 1. 创建复合索引 (user_id, status, create_time) ALTER TABLE orders ADD INDEX idx_user_status_time(user_id, status, create_time); ``` --- 通过以上策略,可显著提升查询性能,但需结合实际业务场景和数据分布进行调整。建议通过监控工具(如Percona Toolkit)持续分析索引有效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值