为了优化查询,添加字段,并在字段上做索引

本文讨论了通过在A表中增加冗余字段并建立索引来优化涉及A表与B表关联查询的方法,提高了查询效率。

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

A表关联B表,条件查询都限定在B表上,并且在B表先做一个查询,然后再关联的,A表无该字段,因此不对A表做限定;
但是
为了优化查询,在A表添加字段,冗余该字段,并在字段上做索引,这样查询效率高点;

select *
from A
join (
select * from B
) t
on A.x = t.x

<think>嗯,用户想了解MySQL索引优化字段定义的最佳实践。首先,我需要回忆一下相关的知识,比如索引的类型、如何选择索引字段、避免索引失效的情况,以及字段定义时的注意事项。记得索引优化包括选择合适的列作为索引,避免过多索引,使用覆盖索引,还有索引下推这些技术。 用户提到的引用内容里有覆盖索引、回表操作,还有排序和分页的优化。比如引用4中提到通过先查主键再关联原表来减少返回字段,这可能和覆盖索引有关。覆盖索引可以减少回表操作,提升查询速度。另外,引用2里提到索引是排好序的数据结构,所以索引的选择和排序优化也相关。 字段定义方面,可能需要考虑数据类型的选择,比如使用较小的数据类型,避免NULL,使用枚举等。这些都能减少存储空间,提高索引效率。还有联合索引的创建顺序,比如最左前缀原则,需要把区分度高的列放在前面。 还要想到索引失效的情况,比如在WHERE子句中使用函数或者运算,会导致索引失效。还有LIKE以通配符开头的情况,也会让索引失效。这些都是常见的优化点。 另外,用户可能想知道如何分析索引使用情况,比如EXPLAIN命令,查看执行计划中的type、key、Extra字段,判断是否使用了索引,是否有文件排序或临时表的问题。 需要整理出具体的优化技巧,分点说明,且结合引用中的内容。比如覆盖索引对应引用3,索引下推可能引用里没提到,但可以结合自己的知识补充。字段定义的最佳实践要包括数据类型、避免NULL、主键设计等。 可能还要提到索引维护,比如定期分析表,更新索引统计信息,删除冗余索引。以及分页查询优化,如使用延迟关联,像引用4中的例子那样改写SQL。 需要确保回答结构清晰,分索引优化字段定义两部分,每个部分列出具体的最佳实践,引用相关的引用内容。最后生成相关问题,帮助用户进一步学习。</think>### MySQL索引优化字段定义最佳实践 --- #### **一、索引优化核心技巧** 1. **选择合适的索引列** - 高频查询字段(如`WHERE`、`JOIN`、`ORDER BY`子句中的字段)应优先建立索引[^2]。 - 区分度高的列(如用户ID)更适合作为索引,区分度公式: $$ \text{区分度} = \frac{\text{COUNT(DISTINCT col)}}{\text{COUNT(*)}} $$ 值越接近1,索引效率越高。 2. **联合索引的最左匹配原则** - 联合索引`(a,b,c)`仅支持`a`、`a,b`、`a,b,c`的查询条件,单独使用`b`或`c`无法触发索引。 3. **覆盖索引减少回表** - 若查询字段全部包含在索引中,直接通过索引树返回结果,避免回表操作[^3]。 例如:`SELECT id,name FROM users WHERE age>20`,若索引为`(age,id,name)`则可覆盖查询。 4. **索引下推(ICP)优化** - MySQL 5.6+支持将`WHERE`条件过滤下推到存储引擎层,减少回表次数。 需满足:查询条件为索引列,且使用`EXPLAIN`显示`Using index condition`。 5. **分页查询优化** - 大偏移量分页时,优先通过子查询获取主键,再关联原表: ```sql SELECT * FROM table INNER JOIN (SELECT id FROM table ORDER BY col LIMIT 100000,10) AS tmp USING(id); ``` 减少排序字段的数据量[^4]。 --- #### **二、字段定义最佳实践** 1. **数据类型优化** - 使用最小可用类型(如`TINYINT`代替`INT`)。 - 字符串字段优先定长类型(如`CHAR`),变长数据用`VARCHAR`但避免过长。 - 避免`NULL`:`NULL`列需额外存储空间,且索引复杂度增加。可设置默认值如`''`或`0`。 2. **数值类型选择** - 整型:`TINYINT`(1字节)、`INT`(4字节)、`BIGINT`(8字节)。 - 浮点型:`DECIMAL`精确计算(如金额),`FLOAT/DOUBLE`用于科学计算。 3. **时间类型选择** - `TIMESTAMP`(4字节,时区自动转换) vs `DATETIME`(8字节,无时区)。 - 高频查询的时间字段(如`create_time`)建议加索引。 4. **枚举与集合** - 有限固定值用`ENUM`(如状态字段`ENUM('active','inactive')`),存储为整型提升效率。 5. **主键设计** - 自增主键`AUTO_INCREMENT`避免页分裂,提升写入性能。 - 业务主键需满足唯一性且尽量简短(如雪花算法生成分布式ID)。 --- #### **三、索引失效场景与规避** 1. **隐式类型转换** ```sql SELECT * FROM users WHERE phone = 13800138000; -- phone为字符串类型,索引失效 ``` 2. **函数或表达式操作** ```sql SELECT * FROM logs WHERE YEAR(create_time)=2023; -- 改为范围查询 ``` 3. **LIKE左模糊匹配** ```sql SELECT * FROM products WHERE name LIKE '%apple%'; -- 无法使用索引 ``` 4. **OR条件未全覆盖** ```sql SELECT * FROM orders WHERE user_id=1 OR amount>100; -- 若仅user_id有索引,整体失效 ``` --- #### **四、分析工具与维护建议** 1. **使用`EXPLAIN`诊断执行计划** - 关注`type`(扫描类型)、`key`(使用索引)、`rows`(扫描行数)、`Extra`(是否临时排序/表)。 2. **定期维护索引** - 删除冗余索引:通过`sys.schema_redundant_indexes`表检测。 - 更新统计信息:`ANALYZE TABLE table_name;`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值