万户网络做网站网站项目怎么做
2026/4/17 17:25:16 网站建设 项目流程
万户网络做网站,网站项目怎么做,vps搭建个人网站,wordpress 认证证书先明确两个核心概念#xff08;基础前提#xff09;测试环境准备#xff08;统一对比基准#xff09;无索引下推#xff08;ICPoff#xff09;#xff1a;服务层做全量过滤#xff0c;回表次数多执行流程#xff08;清晰拆解#xff09;核心问题有索引下推#xff0…先明确两个核心概念基础前提测试环境准备统一对比基准无索引下推ICPoff服务层做全量过滤回表次数多执行流程清晰拆解核心问题有索引下推ICPon存储引擎提前筛回表次数骤减执行流程清晰拆解核心优化点用EXPLAIN验证差异实操层面确认执行计划对比索引下推的适用边界明确能/不能用能生效的场景不能生效的场景总结索引下推ICPIndex Condition Pushdown不是花里胡哨的优化技巧而是MySQL在查询执行阶段的核心逻辑调整。我认为想要真正懂它不用扯生活例子直接从InnoDB存储引擎和MySQL服务层的交互流程入手对比有无下推的执行差异就能一眼看明白。先明确两个核心概念基础前提在聊索引下推前必须先分清MySQL查询的两个核心层级这是理解差异的关键存储引擎层InnoDB负责管理数据存储、索引结构能直接访问索引和数据页执行IO操作。服务层Server负责SQL解析、优化、条件过滤、结果组装不直接接触磁盘IO。联合索引结构以idx_age_city (age, city)为例索引节点中会同时存储age、city的值和对应行的主键id而非叶子节点只存“索引值主键指针”叶子节点存完整索引信息agecityid。测试环境准备统一对比基准先建表、加索引、插数据所有对比都基于这个环境避免变量干扰-- 建表主键id联合索引idx_age_city(age, city)CREATETABLEusers(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(50),ageINT,cityVARCHAR(50),salaryDECIMAL(10,2))ENGINEInnoDB;-- 创建联合索引核心age是前缀列city是非前缀列CREATEINDEXidx_age_cityONusers(age,city);-- 插入测试数据模拟10万行其中age25的有5万行age25且city北京的有8000行INSERTINTOusers(name,age,city,salary)SELECTCONCAT(user_,FLOOR(RAND()*100000)),FLOOR(RAND()*5020),-- age范围20-70IF(FLOOR(RAND()*10)1,北京,上海),-- 10%数据是北京FLOOR(RAND()*100005000)FROMinformation_schema.tablesLIMIT100000;我们要分析的查询SQL固定SELECT*FROMusersWHEREage25ANDcity北京;这条SQL的核心特点age是联合索引前缀列city是联合索引非前缀列查询需要回表因为要查*索引不包含所有列。无索引下推ICPoff服务层做全量过滤回表次数多当关闭索引下推SET optimizer_switch index_condition_pushdownoff查询执行流程是“存储引擎只筛前缀列服务层筛剩余列”具体步骤如下执行流程清晰拆解存储引擎层操作遍历联合索引idx_age_city仅根据age 25这个前缀列条件筛选出所有符合的索引项。对每一个符合age 25的索引项提取对应的主键id共5万条返回给服务层。注意此时存储引擎完全不处理city 北京这个条件哪怕索引里有city字段。服务层操作接收存储引擎返回的5万个主键id逐个发起“回表查询”通过主键id到聚簇索引查完整行数据。对每一行回表得到的完整数据过滤city 北京条件最终只保留8000条符合条件的数据。丢弃剩下的42000条不符合city条件的数据返回最终结果。核心问题无索引下推时存储引擎只利用了索引的前缀列age非前缀列city的过滤完全交给服务层导致无效回表次数暴增42000次无意义的回表IO这是性能损耗的核心。有索引下推ICPon存储引擎提前筛回表次数骤减当开启索引下推MySQL5.6默认开启SET optimizer_switch index_condition_pushdownon核心变化是“存储引擎利用索引中的非前缀列提前过滤”流程如下执行流程清晰拆解存储引擎层操作遍历联合索引idx_age_city先筛选age 25的索引项和无下推一致。关键差异在存储引擎层直接利用索引中存储的city值对筛选出的索引项再做city 北京过滤。只提取过滤后符合“age 25 AND city ‘北京’”的8000个主键id返回给服务层。服务层操作接收8000个主键id仅发起8000次回表查询无无效回表。直接返回这8000条数据无需再过滤city条件。核心优化点索引下推把原本服务层的city过滤逻辑“下推”到存储引擎层利用索引中已有的city数据完成筛选直接减少了42000次回表IO——而磁盘IO是MySQL查询中最耗时的操作这也是性能提升的核心原因。用EXPLAIN验证差异实操层面确认不用猜直接用EXPLAIN看执行计划就能明确索引下推是否生效-- 关闭下推后执行SEToptimizer_switchindex_condition_pushdownoff;EXPLAINSELECT*FROMusersWHEREage25ANDcity北京;-- 开启下推后执行SEToptimizer_switchindex_condition_pushdownon;EXPLAINSELECT*FROMusersWHEREage25ANDcity北京;执行计划对比状态Extra列内容含义说明无索引下推Using where服务层完成所有条件过滤有索引下推Using index condition存储引擎层利用索引完成部分过滤我们的经验是只要Extra列出现Using index condition就说明索引下推生效存储引擎已经帮服务层提前做了索引内的条件过滤。索引下推的适用边界明确能/不能用我认为搞懂适用场景比只知道原理更重要避免盲目依赖能生效的场景仅针对二级索引非聚簇索引聚簇索引主键索引本身存储完整行数据回表无意义下推也无价值。条件包含联合索引的非前缀列比如索引(a,b,c)条件a1 AND b5、a LIKE 张% AND c10非前缀列b/c可被下推。支持range/ref/eq_ref等常见查询类型比如age25range、age30ref都能下推。不能生效的场景用了覆盖索引比如SELECT age,city FROM users WHERE age25 AND city北京无需回表下推无意义。条件包含非索引字段比如age25 AND salary10000salary不在索引中无法下推。OR连接的条件比如age25 OR city北京MySQL暂不支持此类下推。子查询/存储函数条件比如city IN (SELECT city FROM xxx)无法下推。总结索引下推的核心差异无下推时存储引擎只筛索引前缀列服务层全量回表后筛剩余条件有下推时存储引擎利用索引内的非前缀列提前过滤大幅减少回表IO。性能提升的关键减少无效回表次数——回表是磁盘IO操作每少一次查询效率就高一分。验证方法EXPLAIN看Extra列Using index condition即生效Using where则未生效。其实索引下推的本质很简单让离数据最近的存储引擎多做筛选少让服务层做“无用功”。理解了存储引擎和服务层的交互逻辑有无下推的区别就一目了然不用靠生活例子也能精准掌握。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询