MySQL 索引下推(LCP)

MySQL的Index Condition Pushdown (ICP)特性在5.6版本引入,通过在存储引擎层利用索引过滤数据,减少回表操作。本文详细介绍了ICP的工作原理,使用前后的扫描过程差异,以及启用ICP的条件,如仅适用于二级索引,且SQL查询的where条件部分需包含在索引列中。

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

Index Condition Pushdown(ICP)是MySQL 5.6中新特性,是一种在存储引擎层使用索引过滤数据的一种优化方式。

使用前后的扫描过程

在不使用ICP索引扫描的过程:
  • storage层:只将满足index key条件的索引记录对应的整行记录取出,返回给server层
  • server 层:对返回的数据,使用后面的where条件过滤,直至返回最后一行。
    在这里插入图片描述
    在这里插入图片描述
使用ICP扫描的过程:

storage层:
首先将index key条件满足的索引记录区间确定,然后在索引上使用index filter进行过滤。将满足的index filter条件的索引记录才去回表取出整行记录返回server层。不满足index filter条件的索引记录丢弃,不回
表、也不会返回server层。

  • server 层:
    对返回的数据,使用table filter条件做最后的过滤。
    在这里插入图片描述在这里插入图片描述
使用前后的成本差别
  • 使用前,存储层多返回了需要被index filter过滤掉的整行记录
  • 使用ICP后,直接就去掉了不满足index filter条件的记录,省去了他们回表和传递到server层的成本。
  • ICP的 加速效果 取决于在存储引擎内通过 ICP筛选掉的数据的比例。

ICP的使用条件

  1. 只能用于二级索引(secondary index)
  2. explain显示的执行计划中type值(join 类型)为 range 、 ref 、 eq_ref 或者 ref_or_null
  3. 并非全部where条件都可以用ICP筛选,如果where条件的字段不在索引列中,还是要读取整表的记录 到server端做where过滤。
  4. ICP可以用于MyISAM和InnnoDB存储引擎
  5. MySQL 5.6版本的不支持分区表的ICP功能,5.7版本的开始支持。
  6. 当SQL使用覆盖索引时,不支持ICP优化方法。
select left(lcp.managecom,4) branchCode, ld.name institutionName, labg.BranchAttr salesTeamCode, labg.Name salesTeamName, lcp.appntno policyHolder,lcp.insuredno insuredPerson,lcp.contno policyNumber,riskcode productCode, lcp.cvalidate effectiveDate,lcp.prem premium, (select codename from ldcode where codetype='salechnl' and code=lcp.salechnl) salesChannel, la.groupagentcode agentCode, la.name agentName, (select case when la.branchtype = '1' and la.branchtype2 = '01' then '个险直销渠道' when la.branchtype = '1' and la.branchtype2 = '02' then '个险中介渠道' when la.branchtype = '1' and la.branchtype2 = '03' then '个险交叉销售渠道' when la.branchtype = '1' and la.branchtype2 = '05' then '个险续收销售渠道' when la.branchtype = '2' and la.branchtype2 = '01' then '团险直销渠道' when la.branchtype = '2' and la.branchtype2 = '02' then '团险中介渠道' when la.branchtype = '3' and la.branchtype2 = '01' then '银保渠道' when la.branchtype = '4' and la.branchtype2 = '01' then '电话销售渠道' when la.branchtype = '5' and la.branchtype2 = '01' then '互动渠道' when la.branchtype = '6' and la.branchtype2 = '01' then '社保直销渠道' when la.branchtype = '6' and la.branchtype2 = '02' then '社保综拓中介渠道' when la.branchtype = '6' and la.branchtype2 = '03' then '社保中介渠道' when la.branchtype = '7' and la.branchtype2 = '01' then '健管渠道' when la.branchtype = '8' and la.branchtype2 = '02' then '电商渠道' end from lcappnt lc,laagent la where lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName order by la.employdate desc fetch first 1 rows only ) policyHolderSalesChannel, (select la.groupagentcode from lcappnt lc,laagent la where lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName order by la.employdate desc fetch first 1 rows only) policyHolderGroupCode, (select case when agentstate>='06' then '离职' else '在职' end from lcappnt lc,laagent la where lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName and la.groupagentcode is not null order by la.employdate desc fetch first 1 rows only) policyHolderIsEmployed, (select case when la.branchtype = '1' and la.branchtype2 = '01' then '个险直销渠道' when la.branchtype = '1' and la.branchtype2 = '02' then '个险中介渠道' when la.branchtype = '1' and la.branchtype2 = '03' then '个险交叉销售渠道' when la.branchtype = '1' and la.branchtype2 = '05' then '个险续收销售渠道' when la.branchtype = '2' and la.branchtype2 = '01' then '团险直销渠道' when la.branchtype = '2' and la.branchtype2 = '02' then '团险中介渠道' when la.branchtype = '3' and la.branchtype2 = '01' then '银保渠道' when la.branchtype = '4' and la.branchtype2 = '01' then '电话销售渠道' when la.branchtype = '5' and la.branchtype2 = '01' then '互动渠道' when la.branchtype = '6' and la.branchtype2 = '01' then '社保直销渠道' when la.branchtype = '6' and la.branchtype2 = '02' then '社保综拓中介渠道' when la.branchtype = '6' and la.branchtype2 = '03' then '社保中介渠道' when la.branchtype = '7' and la.branchtype2 = '01' then '健管渠道' when la.branchtype = '8' and la.branchtype2 = '02' then '电商渠道' end from lcinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name order by la.employdate desc fetch first 1 rows only ) insuredPersonSalesChannel, (select groupagentcode from lcinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name order by la.employdate desc fetch first 1 rows only) insuredPersonGroupCode, (select case when agentstate>='06' then '离职' else '在职' end from lcinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name and la.groupagentcode is not null order by la.employdate desc fetch first 1 rows only) insuredPersonIsEmployed from lcpol lcp, ldcom ld, LABranchGroup labg, laagent la where lcp.managecom = ld.comcode and la.agentcode=lcp.agentcode and labg.AgentGroup = lcp.AgentGroup and lcp.conttype='1' and lcp.appflag='1' and lcp.cvalidate>= '2025-06-01' and lcp.cvalidate <= '2025-06-11' and salechnl IN ('04','13','14','15') and exists (select 1 from lcappnt lc, laagent la WHERE lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName and la.agentstate < '06' union select 1 from lcinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name and la.agentstate < '06') union select left(lcp.managecom,4) branchCode, ld.name institutionName, labg.BranchAttr salesTeamCode, labg.Name salesTeamName, lcp.appntno policyHolder,lcp.insuredno insuredPerson,lcp.contno policyNumber,riskcode productCode, lcp.cvalidate effectiveDate,lcp.prem premium, (select codename from ldcode where codetype='salechnl' and code=lcp.salechnl) salesChannel, la.groupagentcode agentCode, la.name agentName, (select case when la.branchtype = '1' and la.branchtype2 = '01' then '个险直销渠道' when la.branchtype = '1' and la.branchtype2 = '02' then '个险中介渠道' when la.branchtype = '1' and la.branchtype2 = '03' then '个险交叉销售渠道' when la.branchtype = '1' and la.branchtype2 = '05' then '个险续收销售渠道' when la.branchtype = '2' and la.branchtype2 = '01' then '团险直销渠道' when la.branchtype = '2' and la.branchtype2 = '02' then '团险中介渠道' when la.branchtype = '3' and la.branchtype2 = '01' then '银保渠道' when la.branchtype = '4' and la.branchtype2 = '01' then '电话销售渠道' when la.branchtype = '5' and la.branchtype2 = '01' then '互动渠道' when la.branchtype = '6' and la.branchtype2 = '01' then '社保直销渠道' when la.branchtype = '6' and la.branchtype2 = '02' then '社保综拓中介渠道' when la.branchtype = '6' and la.branchtype2 = '03' then '社保中介渠道' when la.branchtype = '7' and la.branchtype2 = '01' then '健管渠道' when la.branchtype = '8' and la.branchtype2 = '02' then '电商渠道' end from lbappnt lc,laagent la where lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName order by la.employdate desc fetch first 1 rows only ) policyHolderSalesChannel, (select la.groupagentcode from lbappnt lc,laagent la where lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName order by la.employdate desc fetch first 1 rows only) policyHolderGroupCode, (select case when agentstate>='06' then '离职' else '在职' end from lbappnt lc,laagent la where lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName and la.groupagentcode is not null order by la.employdate desc fetch first 1 rows only) policyHolderIsEmployed, (select case when la.branchtype = '1' and la.branchtype2 = '01' then '个险直销渠道' when la.branchtype = '1' and la.branchtype2 = '02' then '个险中介渠道' when la.branchtype = '1' and la.branchtype2 = '03' then '个险交叉销售渠道' when la.branchtype = '1' and la.branchtype2 = '05' then '个险续收销售渠道' when la.branchtype = '2' and la.branchtype2 = '01' then '团险直销渠道' when la.branchtype = '2' and la.branchtype2 = '02' then '团险中介渠道' when la.branchtype = '3' and la.branchtype2 = '01' then '银保渠道' when la.branchtype = '4' and la.branchtype2 = '01' then '电话销售渠道' when la.branchtype = '5' and la.branchtype2 = '01' then '互动渠道' when la.branchtype = '6' and la.branchtype2 = '01' then '社保直销渠道' when la.branchtype = '6' and la.branchtype2 = '02' then '社保综拓中介渠道' when la.branchtype = '6' and la.branchtype2 = '03' then '社保中介渠道' when la.branchtype = '7' and la.branchtype2 = '01' then '健管渠道' when la.branchtype = '8' and la.branchtype2 = '02' then '电商渠道' end from lbinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name order by la.employdate desc fetch first 1 rows only ) insuredPersonSalesChannel, (select groupagentcode from lbinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name order by la.employdate desc fetch first 1 rows only) insuredPersonGroupCode, (select case when agentstate>='06' then '离职' else '在职' end from lbinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name and la.groupagentcode is not null order by la.employdate desc fetch first 1 rows only) insuredPersonIsEmployed from lbpol lcp, ldcom ld, LABranchGroup labg, laagent la where lcp.managecom = ld.comcode and la.agentcode=lcp.agentcode and labg.AgentGroup = lcp.AgentGroup and lcp.conttype='1' and lcp.appflag in ('1','3') and lcp.cvalidate>= '2025-06-01' and lcp.cvalidate <= '2025-06-11' and salechnl IN ('04','13','14','15') and lcp.edorno not like 'xb%' and exists (select 1 from lbappnt lc, laagent la WHERE lc.contno=lcp.contno and lc.appntno=lcp.appntno and la.IDNO = lc.IDNo AND la.NAME = lc.AppntName and la.agentstate < '06' union select 1 from lbinsured lci,laagent la WHERE lci.contno=lcp.contno and lcp.insuredno=lci.insuredno and la.IDNO = lci.IDNo AND la.NAME = lci.Name and la.agentstate < '06') 优化这个db2的sql
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一叶一菩提魁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值