MySQL EXPLAIN实战:6种索引失效场景验证与优化

前置知识:在阅读本文之前,建议先了解EXPLAIN命令的基础知识。如果你还不熟悉EXPLAIN,请先阅读《MySQL EXPLAIN命令详解:SQL查询性能分析与优化指南(基础篇)》。

前言:索引是提升数据库查询性能的重要手段,但并不是所有查询都能有效利用索引。在实际开发中,我们经常遇到索引失效的情况,导致查询性能下降。本文将通过EXPLAIN命令,逐一验证6种常见的索引失效场景,并提供相应的优化建议。

本文将验证以下场景:

  • 场景1:模糊匹配导致索引失效
  • 场景2:函数操作导致索引失效
  • 场景3:表达式计算导致索引失效
  • 场景4:隐式类型转换导致索引失效
  • 场景5:联合索引非最左匹配导致索引失效
  • 场景6:WHERE子句中的OR导致索引失效

一、创建测试表

为了准确验证每个场景,我们采用"按需创建索引"的方式,避免预先创建的索引影响验证结果。

-- 创建员工表(不创建索引,只保留主键)CREATETABLE employees ( id INTPRIMARYKEYAUTO_INCREMENT, name VARCHAR(100), age INT, phone VARCHAR(20), salary DECIMAL(10,2), department_id INT, hire_date DATE);-- 插入测试数据INSERTINTO employees (name, age, phone, salary, department_id, hire_date)VALUES('张三',25,'13800138001',8000.00,1,'2020-01-15'),('李四',30,'13800138002',12000.00,2,'2019-06-20'),('王五',28,'13800138003',9500.00,1,'2021-03-10'),('赵六',35,'13800138004',15000.00,3,'2018-11-05'),('钱七',27,'13800138005',10000.00,2,'2020-08-22'),('张伟',32,'13800138006',13000.00,1,'2019-04-18'),('李娜',29,'13800138007',11000.00,3,'2021-01-30'),('王芳',26,'13800138008',8500.00,2,'2020-12-01'),('赵强',31,'13800138009',14000.00,1,'2018-07-15'),('钱龙',33,'13800138010',16000.00,3,'2017-09-20');-- 查看表结构DESC employees;-- 查看索引(此时只有主键索引)SHOWINDEXFROM employees;

主键索引(Primary Key)

在这里插入图片描述

二、场景1:模糊匹配导致索引失效

2.1 问题分析

问题: 左模糊匹配(LIKE ‘%value’)会导致索引失效

2.2 验证过程

-- 创建name列的索引CREATEINDEX idx_name ON employees(name);-- 1.1 左模糊匹配(索引失效)EXPLAINSELECT*FROM employees WHERE name LIKE'%张';-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 1.2 左右模糊匹配(索引失效)EXPLAINSELECT*FROM employees WHERE name LIKE'%张%';-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 1.3 右模糊匹配(索引生效)EXPLAINSELECT*FROM employees WHERE name LIKE'张%';-- 结果:type = range, key = idx_name(使用索引范围扫描)-- 1.4 精确匹配(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三';-- 结果:type = ref, key = idx_name(使用索引查找)

2.3 结论



分别从左模糊查询和右模糊查询我们可以看出,左模糊查询会导致索引失效,查询使用的是全盘扫描。右模糊查询则是使用到了索引查询。
  • 左模糊(%value)和左右模糊(%value%)会导致索引失效
  • 右模糊(value%)和精确匹配可以使用索引

2.4 优化建议

  • 避免使用左模糊匹配
  • 考虑使用全文索引(FULLTEXT)
  • 使用搜索引擎(如Elasticsearch)

优化示例:

-- 方案1:使用右模糊WHERE name LIKE'张%'-- 方案2:使用全文索引ALTERTABLE employees ADD FULLTEXT INDEX ft_name (name);EXPLAINSELECT*FROM employees WHEREMATCH(name) AGAINST('张'INNATURALLANGUAGEMODE); -- 方案3:使用搜索引擎(如Elasticsearch)-- 适合复杂的全文搜索场景
全文索引

三、场景2:函数操作导致索引失效

3.1 问题分析

问题: 对索引列使用函数会导致索引失效

3.2 验证过程

-- 创建hire_date列的索引CREATEINDEX idx_hire_date ON employees(hire_date);-- 2.1 使用YEAR函数(索引失效)EXPLAINSELECT*FROM employees WHEREYEAR(hire_date)=2020;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 2.2 使用MONTH函数(索引失效)EXPLAINSELECT*FROM employees WHEREMONTH(hire_date)=6;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 2.3 使用UPPER函数(索引失效)EXPLAINSELECT*FROM employees WHERE UPPER(name)='张三';-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 2.4 优化:使用范围查询(索引生效)EXPLAINSELECT*FROM employees WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31';-- 结果:type = range, key = idx_hire_date(使用索引范围扫描)

3.3 结论



对索引使用函数会导致索引失效
  • 对索引列使用函数会破坏索引的有序性,导致索引失效
  • 应将函数操作移到应用层或使用范围查询替代

3.4 优化建议

  • 避免在WHERE子句中对索引列使用函数
  • 将函数操作移到应用层处理
  • 使用计算列或生成列(MySQL 5.7+)

优化示例:

-- 方案1:使用范围查询WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31'-- 方案2:使用计算列(MySQL 5.7+)ALTERTABLE employees ADDCOLUMN hire_year INT GENERATED ALWAYS AS(YEAR(hire_date)) STORED;CREATEINDEX idx_hire_year ON employees(hire_year);WHERE hire_year =2020-- 方案3:应用层处理-- 在应用层计算好年份,然后查询WHERE hire_date >='2020-01-01'AND hire_date <='2020-12-31'

四、场景3:表达式计算导致索引失效

4.1 问题分析

问题: 对索引列进行表达式计算会破坏索引

4.2 验证过程

-- 创建salary和age列的索引CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_age ON employees(age);-- 3.1 索引列参与计算(索引失效)EXPLAINSELECT*FROM employees WHERE salary +1000>10000;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 3.2 索引列参与计算(索引失效)EXPLAINSELECT*FROM employees WHERE age -5>20;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 3.3 索引列参与计算(索引失效)EXPLAINSELECT*FROM employees WHERE salary *1.1>10000;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 3.4 优化:将计算移到右边(索引生效)EXPLAINSELECT*FROM employees WHERE salary >10000-1000;-- 结果:type = range, key = idx_salary(使用索引范围扫描)-- 3.5 优化:直接使用常量(索引生效)EXPLAINSELECT*FROM employees WHERE salary >9000;-- 结果:type = range, key = idx_salary(使用索引范围扫描)

4.3 结论

  • 索引列参与表达式计算会导致索引失效
  • 应将计算移到查询条件的右边或应用层

4.4 优化建议

  • 避免在WHERE子句中对索引列进行计算
  • 将计算移到应用层
  • 使用覆盖索引优化

优化示例:

-- 方案1:将计算移到右边WHERE salary >10000-1000-- 方案2:应用层计算-- 在应用层计算好阈值,然后查询WHERE salary >9000-- 方案3:使用覆盖索引CREATEINDEX idx_salary_bonus ON employees(salary, bonus);WHERE salary + bonus >100000

五、场景4:隐式类型转换导致索引失效

5.1 问题分析

问题: 当查询中数据类型与索引不匹配时,会导致索引失效

5.2 验证过程

-- 创建phone和department_id列的索引CREATEINDEX idx_phone ON employees(phone);CREATEINDEX idx_dept ON employees(department_id);-- 4.1 字符串列使用数字查询(索引失效)-- phone是VARCHAR类型,使用数字查询会导致隐式转换EXPLAINSELECT*FROM employees WHERE phone =13800138001;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 4.2 优化:使用字符串查询(索引生效)EXPLAINSELECT*FROM employees WHERE phone ='13800138001';-- 结果:type = ref, key = idx_phone(使用索引查找)-- 4.3 数字列使用字符串查询(索引可能生效)-- department_id是INT类型EXPLAINSELECT*FROM employees WHERE department_id ='1';-- 结果:type = ref, key = idx_dept(MySQL自动转换,索引可能生效)-- 4.4 日期列使用字符串查询(索引生效)EXPLAINSELECT*FROM employees WHERE hire_date ='2020-01-15';-- 结果:type = ref, key = idx_hire_date(使用索引查找)

5.3 结论

  • 字符串列使用数字查询会导致隐式类型转换,索引失效
  • 应确保查询条件的数据类型与字段类型一致

5.4 优化建议

  • 确保查询条件的数据类型与字段类型一致
  • 使用显式类型转换函数
  • 在应用层进行类型转换

优化示例:

-- 方案1:使用正确的类型WHERE phone ='13800138001'-- 方案2:使用显式类型转换WHERE phone = CAST(13800138001ASCHAR)-- 方案3:应用层类型转换-- 在应用层将数字转换为字符串,然后查询WHERE phone ='13800138001'

六、场景5:联合索引非最左匹配导致索引失效

6.1 问题分析

问题: 联合索引的查询条件不符合最左前缀匹配原则

6.2 验证过程

-- 删除可能影响验证的单列索引DROPINDEXIFEXISTS idx_name ON employees;DROPINDEXIFEXISTS idx_age ON employees;DROPINDEXIFEXISTS idx_dept ON employees;-- 创建联合索引:idx_name_age_dept (name, age, department_id)CREATEINDEX idx_name_age_dept ON employees(name, age, department_id);-- 5.1 使用最左列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三';-- 结果:type = ref, key = idx_name_age_dept, key_len = 403-- 使用了联合索引的第一列-- 5.2 使用最左两列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'AND age =25;-- 结果:type = ref, key = idx_name_age_dept, key_len = 408-- 使用了联合索引的前两列-- 5.3 使用全部三列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'AND age =25AND department_id =1;-- 结果:type = ref, key = idx_name_age_dept, key_len = 412-- 使用了联合索引的全部三列-- 5.4 跳过最左列(索引失效)EXPLAINSELECT*FROM employees WHERE age =25;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 5.5 跳过最左列(索引失效)EXPLAINSELECT*FROM employees WHERE department_id =1;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 5.6 跳过最左列,使用后两列(索引失效)EXPLAINSELECT*FROM employees WHERE age =25AND department_id =1;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 5.7 使用最左列和第三列(部分索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'AND department_id =1;-- 结果:type = ref, key = idx_name_age_dept, key_len = 403-- 只使用了第一列name,跳过了age,department_id未使用-- 5.8 范围查询后的列不生效EXPLAINSELECT*FROM employees WHERE name ='张三'AND age >25AND department_id =1;-- 结果:type = range, key = idx_name_age_dept, key_len = 408-- 只使用了前两列,department_id未使用(因为age是范围查询)

6.3 最左前缀原则

  • 联合索引必须从最左边开始匹配
  • 可以跳过中间的列,但不能跳过最左边的列
  • 范围查询(>、<、BETWEEN、LIKE)后的列不生效

6.4 结论

  • 跳过最左列会导致索引失效
  • 范围查询(>、<、BETWEEN等)后的列无法使用索引
  • 必须从最左边开始匹配

6.5 优化建议

  • 创建联合索引时,将选择性高的列放在前面
  • 根据查询模式设计索引
  • 考虑创建多个单列索引

优化示例:

-- 方案1:遵循最左前缀原则WHERE name ='张三'AND age =25-- 方案2:创建单独的索引CREATEINDEX idx_dept ON employees(department_id);WHERE department_id =1-- 方案3:根据查询模式设计索引-- 如果经常按age查询,创建单独的age索引CREATEINDEX idx_age ON employees(age);WHERE age =25

七、场景6:WHERE子句中的OR导致索引失效

7.1 问题分析

问题: 当查询中存在OR连接的条件时,可能影响索引利用

7.2 验证过程

-- 重新创建单列索引(场景5已删除)CREATEINDEX idx_name ON employees(name);CREATEINDEX idx_age ON employees(age);CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_dept ON employees(department_id);-- 6.1 OR连接不同索引列(索引失效)EXPLAINSELECT*FROM employees WHERE name ='张三'OR age =25;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 6.2 OR连接不同索引列(索引失效)EXPLAINSELECT*FROM employees WHERE salary >10000OR department_id =1;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 6.3 OR连接同一索引列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'OR name ='李四';-- 结果:type = range, key = idx_name(使用索引范围扫描)-- 6.4 优化:使用IN代替OR(索引生效)EXPLAINSELECT*FROM employees WHERE name IN('张三','李四');-- 结果:type = range, key = idx_name(使用索引范围扫描)-- 6.5 优化:使用UNION代替OR(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'UNIONSELECT*FROM employees WHERE age =25;-- 结果:两个查询都使用索引-- 第一个查询:type = ref, key = idx_name-- 第二个查询:type = ref, key = idx_age-- 6.6 OR连接有索引列和无索引列(索引失效)-- 删除salary索引DROPINDEX idx_salary ON employees;EXPLAINSELECT*FROM employees WHERE name ='张三'OR salary >10000;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 重新创建索引CREATEINDEX idx_salary ON employees(salary);

7.3 结论

  • OR连接不同索引列会导致索引失效
  • OR连接同一索引列可以使用索引
  • 可以使用IN或UNION代替OR

7.4 优化建议

  • 尽量使用IN代替OR
  • 使用UNION ALL代替OR(如果确定无重复)
  • 确保OR条件使用同一索引

优化示例:

-- 方案1:使用IN代替ORWHERE name IN('张三','李四')-- 方案2:使用UNION代替ORSELECT*FROM employees WHERE name ='张三'UNIONSELECT*FROM employees WHERE age =25-- 方案3:使用UNION ALL(如果确定无重复)SELECT*FROM employees WHERE name ='张三'UNIONALLSELECT*FROM employees WHERE age =25

八、索引失效场景总结表

场景示例SQL索引状态type优化建议
左模糊匹配WHERE name LIKE '%张'失效ALL使用右模糊或全文索引
左右模糊匹配WHERE name LIKE '%张%'失效ALL使用右模糊或全文索引
右模糊匹配WHERE name LIKE '张%'生效range-
函数操作WHERE YEAR(hire_date) = 2020失效ALL使用范围查询
表达式计算WHERE salary + 1000 > 10000失效ALL计算移到右边
隐式类型转换WHERE phone = 13800138001失效ALL使用字符串类型
联合索引跳过最左列WHERE age = 25失效ALL遵循最左前缀原则
OR连接不同索引列WHERE name = '张' OR age = 25失效ALL使用UNION或IN

九、完整验证脚本

-- ========================================-- 完整验证脚本:从头开始验证所有场景-- ========================================-- 1. 删除已存在的表(如果存在)DROPTABLEIFEXISTS employees;-- 2. 创建员工表(不创建索引)CREATETABLE employees ( id INTPRIMARYKEYAUTO_INCREMENT, name VARCHAR(100), age INT, phone VARCHAR(20), salary DECIMAL(10,2), department_id INT, hire_date DATE);-- 3. 插入测试数据INSERTINTO employees (name, age, phone, salary, department_id, hire_date)VALUES('张三',25,'13800138001',8000.00,1,'2020-01-15'),('李四',30,'13800138002',12000.00,2,'2019-06-20'),('王五',28,'13800138003',9500.00,1,'2021-03-10'),('赵六',35,'13800138004',15000.00,3,'2018-11-05'),('钱七',27,'13800138005',10000.00,2,'2020-08-22'),('张伟',32,'13800138006',13000.00,1,'2019-04-18'),('李娜',29,'13800138007',11000.00,3,'2021-01-30'),('王芳',26,'13800138008',8500.00,2,'2020-12-01'),('赵强',31,'13800138009',14000.00,1,'2018-07-15'),('钱龙',33,'13800138010',16000.00,3,'2017-09-20');-- ========================================-- 场景1:模糊匹配-- ========================================SELECT'========== 场景1:模糊匹配 =========='AS test_case;CREATEINDEX idx_name ON employees(name);SELECT'1.1 左模糊匹配(索引失效)';EXPLAINSELECT*FROM employees WHERE name LIKE'%张';SELECT'1.2 左右模糊匹配(索引失效)';EXPLAINSELECT*FROM employees WHERE name LIKE'%张%';SELECT'1.3 右模糊匹配(索引生效)';EXPLAINSELECT*FROM employees WHERE name LIKE'张%';SELECT'1.4 精确匹配(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三';-- ========================================-- 场景2:函数操作-- ========================================SELECT'========== 场景2:函数操作 =========='AS test_case;CREATEINDEX idx_hire_date ON employees(hire_date);SELECT'2.1 使用YEAR函数(索引失效)';EXPLAINSELECT*FROM employees WHEREYEAR(hire_date)=2020;SELECT'2.2 使用MONTH函数(索引失效)';EXPLAINSELECT*FROM employees WHEREMONTH(hire_date)=6;SELECT'2.3 优化:使用范围查询(索引生效)';EXPLAINSELECT*FROM employees WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31';-- ========================================-- 场景3:表达式计算-- ========================================SELECT'========== 场景3:表达式计算 =========='AS test_case;CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_age ON employees(age);SELECT'3.1 索引列参与计算(索引失效)';EXPLAINSELECT*FROM employees WHERE salary +1000>10000;SELECT'3.2 索引列参与计算(索引失效)';EXPLAINSELECT*FROM employees WHERE age -5>20;SELECT'3.3 优化:将计算移到右边(索引生效)';EXPLAINSELECT*FROM employees WHERE salary >9000;-- ========================================-- 场景4:隐式类型转换-- ========================================SELECT'========== 场景4:隐式类型转换 =========='AS test_case;CREATEINDEX idx_phone ON employees(phone);CREATEINDEX idx_dept ON employees(department_id);SELECT'4.1 字符串列使用数字查询(索引失效)';EXPLAINSELECT*FROM employees WHERE phone =13800138001;SELECT'4.2 优化:使用字符串查询(索引生效)';EXPLAINSELECT*FROM employees WHERE phone ='13800138001';-- ========================================-- 场景5:联合索引非最左匹配-- ========================================SELECT'========== 场景5:联合索引非最左匹配 =========='AS test_case;-- 删除可能影响验证的单列索引DROPINDEX idx_name ON employees;DROPINDEX idx_age ON employees;DROPINDEX idx_dept ON employees;-- 创建联合索引CREATEINDEX idx_name_age_dept ON employees(name, age, department_id);SELECT'5.1 使用最左列(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三';SELECT'5.2 使用最左两列(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三'AND age =25;SELECT'5.3 跳过最左列(索引失效)';EXPLAINSELECT*FROM employees WHERE age =25;SELECT'5.4 跳过最左列,使用后两列(索引失效)';EXPLAINSELECT*FROM employees WHERE age =25AND department_id =1;-- ========================================-- 场景6:OR条件-- ========================================SELECT'========== 场景6:OR条件 =========='AS test_case;-- 重新创建单列索引CREATEINDEX idx_name ON employees(name);CREATEINDEX idx_age ON employees(age);CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_dept ON employees(department_id);SELECT'6.1 OR连接不同索引列(索引失效)';EXPLAINSELECT*FROM employees WHERE name ='张三'OR age =25;SELECT'6.2 OR连接同一索引列(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三'OR name ='李四';SELECT'6.3 优化:使用IN代替OR(索引生效)';EXPLAINSELECT*FROM employees WHERE name IN('张三','李四');-- ========================================-- 验证完成-- ========================================SELECT'========== 验证完成 =========='AS message;SHOWINDEXFROM employees;

十、优化建议总结

10.1 模糊查询优化

-- 避免WHERE name LIKE'%张%'-- 推荐WHERE name LIKE'张%'-- 或使用全文索引WHEREMATCH(name) AGAINST('张')

10.2 函数操作优化

-- 避免WHEREYEAR(hire_date)=2020-- 推荐WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31'

10.3 表达式计算优化

-- 避免WHERE salary +1000>10000-- 推荐WHERE salary >9000

10.4 类型转换优化

-- 避免(phone是VARCHAR类型)WHERE phone =13800138001-- 推荐WHERE phone ='13800138001'

10.5 联合索引优化

-- 联合索引:(name, age, department_id)-- 避免WHERE age =25-- 推荐WHERE name ='张三'AND age =25

10.6 OR条件优化

-- 避免WHERE name ='张三'OR age =25-- 推荐WHERE name IN('张三','李四')-- 或SELECT*FROM employees WHERE name ='张三'UNIONSELECT*FROM employees WHERE age =25

十一、总结

通过EXPLAIN命令验证,我们确认了以下6种常见的索引失效场景:

  1. 模糊匹配:左模糊和左右模糊导致索引失效
  2. 函数操作:对索引列使用函数破坏索引有序性
  3. 表达式计算:索引列参与计算导致索引失效
  4. 隐式类型转换:数据类型不匹配导致索引失效
  5. 联合索引非最左匹配:跳过最左列导致索引失效
  6. OR条件:OR连接不同索引列导致索引失效

关键指标:

  • type = ALL:全表扫描,索引失效
  • key = NULL:未使用索引
  • type = ref/range:使用索引查找/范围扫描
  • key = idx_xxx:使用了指定索引

验证方法:

  • 采用"按需创建索引"的方式,避免预先创建的索引影响验证结果
  • 每个场景独立验证,确保结果准确
  • 提供完整的验证脚本,可以一键运行

通过合理使用EXPLAIN,你可以对查询进行深入分析,找出性能瓶颈,从而提升数据库性能。

延伸阅读:
如果你想了解EXPLAIN命令的基础知识和12个输出字段的详细解释,请阅读我的另一篇文章《MySQL EXPLAIN命令详解:SQL查询性能分析与优化指南(基础篇)》。


Read more

AI 直接生成前端代码:我的软件原型设计流,从此告别重复画图

AI 直接生成前端代码:我的软件原型设计流,从此告别重复画图

近年来,AI 辅助开发越来越成熟,尤其是在快速原型设计方面。今天分享一下我如何借助 Cursor、Trace solo、ChatGPT、Qoder 等 AI 工具,高效完成软件原型的自动绘制与代码生成。 📌 核心流程三步走 1️⃣ 用 AI 输出需求文档(非技术描述) 首先,我会让 AI 根据产品思路或功能描述,生成一份清晰、无技术细节的需求文档。这一步不写代码,只聚焦逻辑与用户流程。 2️⃣ AI 生成 HTML 原型代码 基于上一步的需求文档,直接让 AI 生成对应的 HTML 代码,快速搭建出可交互的前端原型。支持实时预览,直观看到界面效果。 3️⃣ 反复微调,直至满意 生成的原型往往需要多次调整。通过自然语言描述修改方向,AI 可快速迭代代码,直至达到想要的交互与视觉效果。

By Ne0inhk
AI Skills:前端新的效率神器

AI Skills:前端新的效率神器

近来,AI 领域有个火爆的话题:Skills。 Github 上被疯狂 star 的仓库,很多都是和 skills 有关的。 有的仓库仅仅上线三个月就获得了快 50K 的 star,Skills 的火热可见一斑。 不管是大模型,还是 Cursor、Codex、Claude、Trae、Copilot 等编程 IDE 都在争先支持 Skills。 围绕 Skills,它们在做的就是为了完成一件事情:技能是通过学习和反复练习获得的,而 Skills 是把经验和最佳实践沉淀为 AI 能力,将“知道”转化为“做到”的本领。 详解什么是 Skills 要说清楚什么是 Skills,先来了解一下关于 AI 的 2

By Ne0inhk

前端知识点梳理,前端面试复习

一:从输入 URL 到页面渲染是一个经典的综合性考题 1.URL 的标准组成部分 一个完整的 URL 结构如下: scheme://host:port/path?query#fragment URI 用字符串标识某一互联网资源,而URL 表示资源的地点(互 联网上所处的位置)。可见URL是URI 的子集。 URI 和 URL 的区别? * URI (Uniform Resource Identifier) 是统一资源标识符,是一个大概念。 * URL (Uniform Resource Locator) 是统一资源定位符,它不仅标识资源,还提供了找到资源的方式(比如协议)。可以理解为 URL 是 URI 的子集。 为什么 URL 中有些字符会被转义(

By Ne0inhk