<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>性能优化 on 追风笔记</title><link>https://4f0a9a3b.wangpeng.pages.dev/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/</link><description>Recent content in 性能优化 on 追风笔记</description><generator>Hugo</generator><language>zh</language><lastBuildDate>Tue, 25 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://4f0a9a3b.wangpeng.pages.dev/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/index.xml" rel="self" type="application/rss+xml"/><item><title>MySQL 索引原理与最佳实践</title><link>https://4f0a9a3b.wangpeng.pages.dev/tech/mysql/indexing/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://4f0a9a3b.wangpeng.pages.dev/tech/mysql/indexing/</guid><description>&lt;p&gt;索引是 MySQL 查询性能的决定性因素。理解 InnoDB 的 B+Tree 索引结构，才能写出真正命中索引的 SQL。&lt;/p&gt;&#10;&lt;h2 id="btree-与聚簇索引"&gt;B+Tree 与聚簇索引&#10;&lt;/h2&gt;&#10;&lt;p&gt;InnoDB 使用 B+Tree 组织索引，其特点是非叶子节点只存索引键用于导航，所有数据都落在叶子节点，且叶子节点通过双向链表串联，非常适合范围扫描。&lt;/p&gt;&#10;&lt;p&gt;InnoDB 的主键索引是&lt;strong&gt;聚簇索引&lt;/strong&gt;，叶子节点直接存放整行数据；二级索引的叶子节点存放「索引键 + 主键值」。因此通过二级索引查询非索引列时，需要再用主键回表查聚簇索引。&lt;/p&gt;&#10;&lt;h2 id="回表与覆盖索引"&gt;回表与覆盖索引&#10;&lt;/h2&gt;&#10;&lt;p&gt;当查询的列都在二级索引中时，无需回表，称为&lt;strong&gt;覆盖索引&lt;/strong&gt;，性能更好：&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-5f7f444b-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="sql" data-td-line-count="3"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-5f7f444b-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- idx_user_age 为 (name, age) 的联合索引&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 仅取索引列，命中覆盖索引&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tom&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;若 &lt;code&gt;SELECT *&lt;/code&gt; 还需要 &lt;code&gt;phone&lt;/code&gt; 等额外列，则会触发回表。高频查询应优先设计为覆盖索引。&lt;/p&gt;&#10;&lt;h2 id="最左前缀原则"&gt;最左前缀原则&#10;&lt;/h2&gt;&#10;&lt;p&gt;联合索引 &lt;code&gt;(a, b, c)&lt;/code&gt; 能生效的条件是查询从最左列开始连续匹配：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;WHERE a = ?&lt;/code&gt; 可用&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;WHERE a = ? AND b = ?&lt;/code&gt; 可用&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;WHERE b = ?&lt;/code&gt; 无法使用该联合索引（断开了最左前缀）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="避免索引失效"&gt;避免索引失效&#10;&lt;/h2&gt;&#10;&lt;p&gt;常见导致索引失效的写法：&lt;/p&gt;</description></item></channel></rss>