30条书写高质量SQL的意见,太有用了!
<span style="color: black;">“</span><p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">本文将结合实例 demo,阐述 30 条<span style="color: black;">相关</span>于优化 SQL 的<span style="color: black;">意见</span>,<span style="color: black;">都数</span>是<span style="color: black;">实质</span><span style="color: black;">研发</span>中总结出来的,<span style="color: black;">期盼</span>对<span style="color: black;">大众</span>有<span style="color: black;">帮忙</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/MOwlO0INfQrLVT1AtdayISHCicb6jg78kepG0MgibMPL3Cy6sz9lhVhbFlj5WEzfDjicQWu1taflYR1sUMGrodJAg/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;"><span style="color: black;">照片</span>来自 Pexels</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">1</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">查找</span> SQL <span style="color: black;">尽可能</span>不要<span style="color: black;">运用</span> select *,而是 select <span style="color: black;">详细</span>字段</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例子:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> employee;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例子:</span></p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span> <span style="color: black;">from</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> employee;</p><span style="color: black;">理由如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">只取<span style="color: black;">必须</span>的字段,节省资源、减少网络开销。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">select * 进行<span style="color: black;">查找</span>时,很可能就不会<span style="color: black;">运用</span>到覆盖索引了,就会<span style="color: black;">导致</span>回表<span style="color: black;">查找</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">2</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">倘若</span><span style="color: black;">晓得</span><span style="color: black;">查找</span>结果<span style="color: black;">仅有</span>一条<span style="color: black;">或</span>只要最大/最小一条记录,<span style="color: black;">意见</span>用 limit 1</span></strong></h3>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">假设<span style="color: black;">此刻</span>有 employee 员工表,要找出一个名字叫 jay 的人:</span></h3><span style="color: black;">CREATE</span> <span style="color: black;">TABLE</span> <span style="color: black;">`employee`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> (</p> <span style="color: black;">`id`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`name`</span> <span style="color: black;">varchar</span>(<span style="color: black;">255</span>) <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`age`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`date`</span> datetime <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`sex`</span> <span style="color: black;">int</span>(<span style="color: black;">1</span>) <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> PRIMARY <span style="color: black;">KEY</span> (<span style="color: black;">`id`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>) <span style="color: black;">ENGINE</span>=<span style="color: black;">InnoDB</span> <span style="color: black;">DEFAULT</span> <span style="color: black;">CHARSET</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">=utf8;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span> <span style="color: black;">from</span> employee <span style="color: black;">where</span> <span style="color: black;">name</span>=<span style="color: black;">jay</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span> <span style="color: black;">from</span> employee <span style="color: black;">where</span> <span style="color: black;">name</span>=<span style="color: black;">jay</span> <span style="color: black;">limit</span> <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><span style="color: black;">理由如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">加上 limit 1 后,只要找到了对应的一条记录,就不会继续向下扫描了,效率将会大大<span style="color: black;">加强</span>。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">当然,<span style="color: black;">倘若</span> name 是<span style="color: black;">独一</span>索引的话,是不必要加上 limit 1 了,<span style="color: black;">由于</span> limit 的存在<span style="color: black;">重点</span><span style="color: black;">便是</span>为了防止全表扫描,从而<span style="color: black;">加强</span>性能,<span style="color: black;">倘若</span>一个语句本身<span style="color: black;">能够</span>预知<span style="color: black;">不消</span>全表扫描,有<span style="color: black;">无</span> limit ,性能的差别并不大。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">3</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">应<span style="color: black;">尽可能</span>避免在 where 子句中<span style="color: black;">运用</span> or 来连接<span style="color: black;">要求</span></span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">新建一个 user 表,它有一个普通索引 userId,表结构如下:</span></p><span style="color: black;">CREATE</span> <span style="color: black;">TABLE</span> <span style="color: black;">`user`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> (</p> <span style="color: black;">`id`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> AUTO_INCREMENT,</p> <span style="color: black;">`userId`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`age`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`name`</span> <span style="color: black;">varchar</span>(<span style="color: black;">255</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> PRIMARY <span style="color: black;">KEY</span> (<span style="color: black;">`id`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">),</p> <span style="color: black;">KEY</span> <span style="color: black;">`idx_userId`</span> (<span style="color: black;">`userId`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>) <span style="color: black;">ENGINE</span>=<span style="color: black;">InnoDB</span> <span style="color: black;">DEFAULT</span> <span style="color: black;">CHARSET</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">=utf8;</p><span style="color: black;">假设<span style="color: black;">此刻</span><span style="color: black;">必须</span><span style="color: black;">查找</span> userid 为 1 <span style="color: black;">或</span>年龄为 18 岁的用户,很容易有以下 SQL。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid=<span style="color: black;">1</span> <span style="color: black;">or</span> age =<span style="color: black;">18</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//<span style="color: black;">运用</span>union all </p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid=<span style="color: black;">1</span><span style="color: black;">union</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> all </p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age = <span style="color: black;">18</span>//<span style="color: black;">或</span><span style="color: black;">掰开</span>两条<span style="color: black;">sql</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">写:</p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span>userid=<span style="color: black;">1</span><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age = <span style="color: black;">18</span><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;"><span style="color: black;">运用</span> or 可能会使索引失效,从而全表扫描。</span><span style="color: black;"><span style="color: black;">针对</span> or+<span style="color: black;">无</span>索引的 age 这种<span style="color: black;">状况</span>,假设它走了 userId 的索引,<span style="color: black;">然则</span><span style="color: black;">步行到</span> age <span style="color: black;">查找</span><span style="color: black;">要求</span>时,它还得全表扫描,<span style="color: black;">亦</span><span style="color: black;">便是</span><span style="color: black;">必须</span>三步过程:全表扫描+索引扫描+合并,<span style="color: black;">倘若</span>它一<span style="color: black;">起始</span>就走全表扫描,直接一遍扫描就完事。</span><span style="color: black;">MySQL 是有优化器的,<span style="color: black;">处在</span>效率与成本<span style="color: black;">思虑</span>,遇到 or <span style="color: black;">要求</span>,索引可能失效,看起来<span style="color: black;">亦</span>合情<span style="color: black;">恰当</span>。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">4</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">优化 limit 分页</span></strong></h3><span style="color: black;"><span style="color: black;">咱们</span><span style="color: black;">平常</span>做分页需求时,<span style="color: black;">通常</span>会用 limit 实现,<span style="color: black;">然则</span>当偏移量<span style="color: black;">尤其</span>大的时候,<span style="color: black;">查找</span>效率就变得低下。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span>,age <span style="color: black;">from</span>employee<span style="color: black;">limit</span> <span style="color: black;">10000</span>,<span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//<span style="color: black;">方法</span>一 :返回上次<span style="color: black;">查找</span>的最大记录(偏移量)</p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span> <span style="color: black;">from</span> employee <span style="color: black;">where</span> <span style="color: black;">id</span>><span style="color: black;">10000</span> <span style="color: black;">limit</span> <span style="color: black;">10.</span>//<span style="color: black;">方法</span>二:<span style="color: black;">order</span> <span style="color: black;">by</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> + 索引</p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span> <span style="color: black;">from</span> employee <span style="color: black;">order</span> <span style="color: black;">by</span> <span style="color: black;">id</span> <span style="color: black;">limit</span> <span style="color: black;">10000</span>,<span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//<span style="color: black;">方法</span>三:在业务<span style="color: black;">准许</span>的<span style="color: black;">状况</span>下限制页数:</p><span style="color: black;">理由如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">当偏移量最大的时候,<span style="color: black;">查找</span>效率就会越低,<span style="color: black;">由于</span> MySQL 并非是跳过偏移量直接去取后面的数据,而是先把偏移量+要取的条数,<span style="color: black;">而后</span>再把前面偏移量这一段的数据抛弃掉再返回的。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">倘若</span><span style="color: black;">运用</span>优化<span style="color: black;">方法</span>一,返回上次最大<span style="color: black;">查找</span>记录(偏移量),<span style="color: black;">这般</span><span style="color: black;">能够</span>跳过偏移量,效率<span style="color: black;">提高</span>不少。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">方法</span>二<span style="color: black;">运用</span> order by+索引,<span style="color: black;">亦</span>是<span style="color: black;">能够</span><span style="color: black;">加强</span><span style="color: black;">查找</span>效率的。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">方法</span>三的话,<span style="color: black;">意见</span>跟业务讨论,有<span style="color: black;">无</span>必要查这么后的分页啦。<span style="color: black;">由于</span>绝大<span style="color: black;">都数</span>用户都不会往后翻太多页。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">5</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">优化你的 like 语句</span></strong></h3><span style="color: black;"><span style="color: black;">平常</span><span style="color: black;">研发</span>中,<span style="color: black;">倘若</span>用到模糊关键字<span style="color: black;">查找</span>,很容易想到 like,<span style="color: black;">然则</span> like 很可能让你的索引失效。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span>userId,<span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userId <span style="color: black;">like</span> <span style="color: black;">%123</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> userId,<span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userId <span style="color: black;">like</span> <span style="color: black;">123%</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">把 % 放前面,并不走索引,如下图: </span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kyW89vDuKpa4jM5Q6eSLpPJibGELC6S5GjKuZ1piaNyM5XAjthiavMBBJA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">把% 放关键字后面,还是会走索引的,如下图: </span></p><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kcC3TBWsmXQRQJPfSSGgICIn9E3SkJBGxRmo7ic7Z0r7b9UCiaUbGDDbQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">6</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">运用</span> where <span style="color: black;">要求</span>限定要<span style="color: black;">查找</span>的数据,避免返回多余的行</span></strong></h3><span style="color: black;">假设业务场景是<span style="color: black;">这般</span>:<span style="color: black;">查找</span>某个用户<span style="color: black;">是不是</span>是会员。曾经看过老的实现代码是<span style="color: black;">这般</span>。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p>List<<span style="color: black;">Long</span>> userIds = sqlMap.queryList(<span style="color: black;">"select userId from user where isVip=1"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p><span style="color: black;">boolean</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">isVip = userIds.contains(userId);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>Long userId = sqlMap.queryObject("<span style="color: black;">select</span> userId <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userId=<span style="color: black;">userId</span> <span style="color: black;">and</span> isVip=<span style="color: black;">1</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">")</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">boolean isVip = userId!=null;</p>
</span><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;"><span style="color: black;">必须</span>什么数据,就去查什么数据,避免返回不必要的数据,节省开销。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">7</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">尽可能</span>避免在索引列上<span style="color: black;">运用</span> MySQL 的内置函数</span></strong></h3><span style="color: black;">业务需求:<span style="color: black;">查找</span><span style="color: black;">近期</span>七天内登陆过的用户(假设 loginTime 加了索引)。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> userId,loginTime <span style="color: black;">from</span> loginuser <span style="color: black;">where</span> <span style="color: black;">Date_ADD</span>(loginTime,<span style="color: black;">Interval</span> <span style="color: black;">7</span> <span style="color: black;">DAY</span>) >=<span style="color: black;">now</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">();</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">explain</span> <span style="color: black;">select</span> userId,loginTime <span style="color: black;">from</span> loginuser <span style="color: black;">where</span> loginTime >= <span style="color: black;">Date_ADD</span>(<span style="color: black;">NOW</span>(),<span style="color: black;">INTERVAL</span> - <span style="color: black;">7</span> <span style="color: black;">DAY</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">索引列上<span style="color: black;">运用</span> MySQL 的内置函数,索引失效:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kibekicJ6eHEBd7ZdibdQpiangYWBteBAxpZOoRSDuxMGjickDz88Rw9rjWw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;"><span style="color: black;">倘若</span>索引列不加内置函数,索引还是会走的:</span><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kpNiaFZm0h6ycUEy8MibDC5CWVJzfZnU1vzsqqcEDLYvugveJIhVb4ziaQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">8</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">应<span style="color: black;">尽可能</span>避免在 where 子句中对字段进行表达式操作,这将<span style="color: black;">引起</span>系统放弃<span style="color: black;">运用</span>索引而进行全表扫</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age<span style="color: black;">-1</span> =<span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age =<span style="color: black;">11</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">虽然 age 加了索引,<span style="color: black;">然则</span><span style="color: black;">由于</span>对它进行运算,索引直接迷路了。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kgcFO77W4om7AQws6FkgcT3uOjUM9mJwmAwLaff4AzRejAlW0RyzicBQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">9</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">Inner join 、left join、right join,优先<span style="color: black;">运用</span> Inner join,<span style="color: black;">倘若</span>是 left join,左边表结果<span style="color: black;">尽可能</span>小</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">Inner join 内连接,在两张表进行连接<span style="color: black;">查找</span>时,只<span style="color: black;">保存</span>两张表中完全匹配的结果集。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">left join 在两张表进行连接<span style="color: black;">查找</span>时,会返回左表所有的行,即使在右表中<span style="color: black;">无</span>匹配的记录。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">right join 在两张表进行连接<span style="color: black;">查找</span>时,会返回右表所有的行,即使在左表中<span style="color: black;">无</span>匹配的记录。</span></p><span style="color: black;">都满足 SQL 需求的前提下,<span style="color: black;">举荐</span>优先<span style="color: black;">运用</span> Inner join(内连接),<span style="color: black;">倘若</span>要<span style="color: black;">运用</span> left join,左边表数据结果<span style="color: black;">尽可能</span>小,<span style="color: black;">倘若</span>有<span style="color: black;">要求</span>的<span style="color: black;">尽可能</span>放到左边处理。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span>tab1 t1<span style="color: black;">left</span> <span style="color: black;">join</span> tab2 t2 <span style="color: black;">on</span> t1.size = t2.size <span style="color: black;">where</span> t1.id><span style="color: black;">2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> (<span style="color: black;">select</span> * <span style="color: black;">from</span> tab1 <span style="color: black;">where</span> <span style="color: black;">id</span> ><span style="color: black;">2</span>) t1 <span style="color: black;">left</span> <span style="color: black;">join</span> tab2 t2 <span style="color: black;">on</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> t1.size = t2.size;</p><span style="color: black;">理由如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">倘若</span> inner join 是等值连接,或许返回的行数比较少,<span style="color: black;">因此</span>性能相对会好一点。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">同理,<span style="color: black;">运用</span>了左连接,左边表数据结果<span style="color: black;">尽可能</span>小,<span style="color: black;">要求</span><span style="color: black;">尽可能</span>放到左边处理,<span style="color: black;">寓意</span>着返回的行数可能比较少。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">10</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">应<span style="color: black;">尽可能</span>避免在 where 子句中<span style="color: black;">运用</span>!=或<>操作符,否则将引擎放弃<span style="color: black;">运用</span>索引而进行全表扫描</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> age,<span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span>age <><span style="color: black;">18</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//<span style="color: black;">能够</span><span style="color: black;">思虑</span><span style="color: black;">掰开</span>两条sql写</p><span style="color: black;">select</span> age,<span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age <<span style="color: black;">18</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><span style="color: black;">select</span> age,<span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age ><span style="color: black;">18</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">理由:</span><span style="color: black;"><span style="color: black;">运用</span>!=和<>很可能会让索引失效:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kqW7NBFdS3VbjfoHs2lNgjYbkDpdRy0hYjzAy7c094PMjsicLAiaaSaZA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">11</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">运用</span>联合索引时,<span style="color: black;">重视</span>索引列的<span style="color: black;">次序</span>,<span style="color: black;">通常</span>遵循最左匹配原则</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">表结构:(有一个联合索引 idxuseridage,userId 在前,age 在后)</span></p><span style="color: black;">CREATE</span> <span style="color: black;">TABLE</span> <span style="color: black;">`user`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> (</p> <span style="color: black;">`id`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> AUTO_INCREMENT,</p> <span style="color: black;">`userId`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`age`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">`name`</span> <span style="color: black;">varchar</span>(<span style="color: black;">255</span>)<span style="color: black;">NOT</span> <span style="color: black;">NULL</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> PRIMARY <span style="color: black;">KEY</span> (<span style="color: black;">`id`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">),</p> <span style="color: black;">KEY</span> <span style="color: black;">`idx_userid_age`</span> (<span style="color: black;">`userId`</span>,<span style="color: black;">`age`</span>) <span style="color: black;">USING</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> BTREE</p>) <span style="color: black;">ENGINE</span>=<span style="color: black;">InnoDB</span> AUTO_INCREMENT=<span style="color: black;">2</span> <span style="color: black;">DEFAULT</span> <span style="color: black;">CHARSET</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">=utf8;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age = <span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kjpOBiaqGr2xia5siciaNMjWV2NJQspNVXFZZ2tcLnDPZfGaLaWrTlGZCicA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//符合最左匹配原则</p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid=<span style="color: black;">10</span> <span style="color: black;">and</span> age =<span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//符合最左匹配原则</p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid =<span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78k3t6rHOB4iaJOWydDro1ZHdIbDDYxo2Lgcx6kPfvhT8kUl05Wem7ecug/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78ktokJL4t2Z5oOsRdCXuHh2yZ2ruaegjeqWn5L6TyWarAzHBDg9S1bcw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">理由如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">当<span style="color: black;">咱们</span>创建一个联合索引的时候,如(k1,k2,k3),相当于创建了(k1)、(k1,k2)和(k1,k2,k3)三个索引,这<span style="color: black;">便是</span>最左匹配原则。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">联合索引不满足最左原则,索引<span style="color: black;">通常</span>会失效,<span style="color: black;">然则</span>这个还跟 MySQL 优化器<span style="color: black;">相关</span>的。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">12</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">对<span style="color: black;">查找</span>进行优化,应<span style="color: black;">思虑</span>在 where 及 order by <span style="color: black;">触及</span>的列上<span style="color: black;">创立</span>索引,<span style="color: black;">尽可能</span>避免全表扫描。</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> address =<span style="color: black;">深圳</span> <span style="color: black;">order</span> <span style="color: black;">by</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> age ;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78k9FAYg4K8aklTc5DjujECqnicptYxGBibuQOlbOia0H8h1DfkXI0FPIoibg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">添加索引</p><span style="color: black;">alter</span> <span style="color: black;">table</span> <span style="color: black;">user</span> <span style="color: black;">add</span> <span style="color: black;">index</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> idx_address_age (address,age)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kjbR14XPofwico2QclXGcfY9mXlPRYONC2AiaxJs4XibdAibQydNSBlHxLg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">13</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">倘若</span><span style="color: black;">插进</span>数据<span style="color: black;">太多</span>,<span style="color: black;">思虑</span>批量<span style="color: black;">插进</span></span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">for</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(User u :list){</p> INSERT into user(name,age) <span style="color: black;">values</span>(<span style="color: black;">#name#,#age#)</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//一次500批量<span style="color: black;">插进</span>,分批进行</p><span style="color: black;">insert</span> <span style="color: black;">into</span> <span style="color: black;">user</span>(<span style="color: black;">name</span>,age) <span style="color: black;">values</span><foreach collection=<span style="color: black;">"list"</span> item=<span style="color: black;">"item"</span> <span style="color: black;">index</span>=<span style="color: black;">"index"</span> separator=<span style="color: black;">","</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">></p> (<span style="color: black;">#{item.name},#{item.age})</span><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">批量<span style="color: black;">插进</span>性能好,更加省时间。</span><span style="color: black;">打个比喻:假如你<span style="color: black;">必须</span>搬一万块砖到楼顶,你有一个电梯,电梯一次<span style="color: black;">能够</span>放适量的砖(最多放 500),你<span style="color: black;">能够</span><span style="color: black;">选取</span>一次运送<span style="color: black;">一起</span>砖,<span style="color: black;">亦</span><span style="color: black;">能够</span>一次运送 500 块砖,你觉得哪个时间消耗大?</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">14</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">在适当的时候,<span style="color: black;">运用</span>覆盖索引</span></strong></h3><span style="color: black;">覆盖索引能够使得你的 SQL 语句不<span style="color: black;">必须</span>回表,仅仅<span style="color: black;">拜访</span>索引就能够得到所有<span style="color: black;">必须</span>的数据,大大<span style="color: black;">加强</span>了<span style="color: black;">查找</span>效率。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">// like模糊<span style="color: black;">查找</span>,不走索引了</span><span style="color: black;">select</span> * <span style="color: black;">from</span> user <span style="color: black;">where</span> userid like <span style="color: black;">%123%</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78k2tdiaObah91UkBSDokicAjfyMbvLicRqicAGyzZgZTPo3BRia3BTQegdwtg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//id为主键,<span style="color: black;">那样</span>为普通索引,即覆盖索引登场了。</p><span style="color: black;">select</span> <span style="color: black;">id</span>,<span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid <span style="color: black;">like</span> <span style="color: black;">%123%</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/MOwlO0INfQrLVT1AtdayISHCicb6jg78kw2RqIZ3qcc5d3vCXBAwib9oRiclKQiaDuTRQiaZiaCunMCFmYPCc1LwOzGw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">15</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">慎用 distinct 关键字</span></strong></h3><span style="color: black;">distinct 关键字<span style="color: black;">通常</span>用来过滤重复记录,以返回不重复的记录。在<span style="color: black;">查找</span>一个字段<span style="color: black;">或</span>很少字段的<span style="color: black;">状况</span>下<span style="color: black;">运用</span>时,给<span style="color: black;">查找</span>带来优化效果。<span style="color: black;">然则</span>在字段<span style="color: black;">非常多</span>的时候<span style="color: black;">运用</span>,却会大大降低<span style="color: black;">查找</span>效率。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">SELECT</span> <span style="color: black;">DISTINCT</span> * <span style="color: black;">from</span> <span style="color: black;">user</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> <span style="color: black;">DISTINCT</span> <span style="color: black;">name</span> <span style="color: black;">from</span> <span style="color: black;">user</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">带 distinct 的语句 CPU 时间和占用时间都高于不带 distinct 的语句。</span><span style="color: black;"><span style="color: black;">由于</span>当<span style="color: black;">查找</span><span style="color: black;">非常多</span>字段时,<span style="color: black;">倘若</span><span style="color: black;">运用</span> distinct,数据库引擎就会对数据进行比较,过滤掉重复数据,然而这个比较、过滤的过程会占用系统资源,CPU 时间。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">16</strong></p><strong style="color: blue;"><span style="color: black;">删除冗余和重复索引</span></strong>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p> KEY <span style="color: black;">`idx_userId`</span> (<span style="color: black;">`userId`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">) </p> KEY <span style="color: black;">`idx_userId_age`</span> (<span style="color: black;">`userId`</span>,<span style="color: black;">`age`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p> <span style="color: black;">//删除userId索引,<span style="color: black;">由于</span>组合索引(A,B)相当于创建了(A)和(A,B)索引</span> KEY <span style="color: black;">`idx_userId_age`</span> (<span style="color: black;">`userId`</span>,<span style="color: black;">`age`</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">重复的索引<span style="color: black;">必须</span><span style="color: black;">守护</span>,并且优化器在优化<span style="color: black;">查找</span>的时候<span style="color: black;">亦</span><span style="color: black;">必须</span>逐个地进行<span style="color: black;">思虑</span>,这会影响性能的。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">17</strong></p><strong style="color: blue;"><span style="color: black;"><span style="color: black;">倘若</span>数据量<span style="color: black;">很强</span>,优化你的修改/删除语句</span></strong><span style="color: black;">避免<span style="color: black;">同期</span>修改或删除<span style="color: black;">太多</span>数据,<span style="color: black;">由于</span>会<span style="color: black;">导致</span> CPU 利用率过高,从而影响别人对数据库的<span style="color: black;">拜访</span>。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">//一次删除10万<span style="color: black;">或</span>100万+?</span><span style="color: black;">delete</span> <span style="color: black;">from</span> user where id <<span style="color: black;">100000</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><span style="color: black;">//<span style="color: black;">或</span>采用单一循环操作,效率低,时间漫长</span><span style="color: black;">for</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(User user:list){</p> <span style="color: black;">delete</span> <span style="color: black;">from</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> user; </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//分批进行删除,如每次500</p><span style="color: black;">delete</span> <span style="color: black;">user</span> <span style="color: black;">where</span> <span style="color: black;">id</span><<span style="color: black;">500</span><span style="color: black;">delete</span> product <span style="color: black;">where</span> <span style="color: black;">id</span>>=<span style="color: black;">500</span> <span style="color: black;">and</span> <span style="color: black;">id</span><<span style="color: black;">1000</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">一次性删除太<span style="color: black;">都数</span>据,可能会有 lock wait timeout exceed 的错误,<span style="color: black;">因此</span><span style="color: black;">意见</span>分批操作。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">18</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">where 子句中<span style="color: black;">思虑</span><span style="color: black;">运用</span>默认值代替 null</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age <span style="color: black;">is</span> <span style="color: black;">not</span> <span style="color: black;">null</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//设置0为默认值</p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age><span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">并不是说<span style="color: black;">运用</span>了 is null <span style="color: black;">或</span> is not null 就会不走索引了,这个跟 MySQL 版本以及<span style="color: black;">查找</span>成本都<span style="color: black;">相关</span>。</span><span style="color: black;"><span style="color: black;">倘若</span> MySQL 优化器<span style="color: black;">发掘</span>,走索引比不走索引成本还要高,肯定会放弃索引,这些<span style="color: black;">要求</span> !=,>isnull,isnotnull 经常被认为让索引失效,其实是<span style="color: black;">由于</span><span style="color: black;">通常</span><span style="color: black;">状况</span>下,<span style="color: black;">查找</span>的成本高,优化器自动放弃索引的。</span><span style="color: black;"><span style="color: black;">倘若</span>把 null 值,换成默认值,<span style="color: black;">非常多</span>时候让走索引<span style="color: black;">作为</span>可能,<span style="color: black;">同期</span>,表达意思会相对清晰一点。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">19</strong></p><strong style="color: blue;"><span style="color: black;">不要有超过 5 个以上的表连接</span></strong>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">连表越多,编译的时间和开销<span style="color: black;">亦</span>就越大。</span><span style="color: black;">把连接表拆开成较小的几个执行,可读性更高。<span style="color: black;">倘若</span><span style="color: black;">必定</span><span style="color: black;">必须</span>连接<span style="color: black;">非常多</span>表<span style="color: black;">才可</span>得到数据,<span style="color: black;">那样</span><span style="color: black;">寓意</span>着糟糕的设计了。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">20</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">exist&in 的<span style="color: black;">恰当</span>利用</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">假设表 A <span style="color: black;">暗示</span>某企业的员工表,表B<span style="color: black;">暗示</span><span style="color: black;">分部</span>表,<span style="color: black;">查找</span>所有<span style="color: black;">分部</span>的所有员工,很容易有以下 SQL:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> A <span style="color: black;">where</span> deptId <span style="color: black;">in</span> (<span style="color: black;">select</span> deptId <span style="color: black;">from</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> B);</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">这般</span>写等价于:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">先<span style="color: black;">查找</span><span style="color: black;">分部</span>表B</p><span style="color: black;">select</span> deptId <span style="color: black;">from</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> B</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">再由<span style="color: black;">分部</span>deptId,<span style="color: black;">查找</span>A的员工</p><span style="color: black;">select</span> * <span style="color: black;">from</span> A <span style="color: black;">where</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">A.deptId = B.deptId</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">能够</span>抽象成<span style="color: black;">这般</span>的一个循环:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> List<> resultSet ;</p> <span style="color: black;">for</span>(<span style="color: black;">int</span> i=<span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;i</p> <span style="color: black;">for</span>(<span style="color: black;">int</span> j=<span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;j</p> <span style="color: black;">if</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(A.id==B.id) {</p> resultSet.<span style="color: black;">add</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(A);</p> <span style="color: black;">break</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">显然,除了<span style="color: black;">运用</span> in,<span style="color: black;">咱们</span><span style="color: black;">亦</span><span style="color: black;">能够</span>用 exists 实现<span style="color: black;">同样</span>的查询功能,如下:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> A <span style="color: black;">where</span> <span style="color: black;">exists</span> (<span style="color: black;">select</span> <span style="color: black;">1</span> <span style="color: black;">from</span> B <span style="color: black;">where</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> A.deptId = B.deptId); </p><span style="color: black;"><span style="color: black;">由于</span> exists <span style="color: black;">查找</span>的理解<span style="color: black;">便是</span>,先执行主<span style="color: black;">查找</span>,<span style="color: black;">得到</span>数据后,再放到子<span style="color: black;">查找</span>中做<span style="color: black;">要求</span>验证,<span style="color: black;">按照</span>验证结果(true <span style="color: black;">或</span> false),来决定主<span style="color: black;">查找</span>的数据结果<span style="color: black;">是不是</span>得意<span style="color: black;">保存</span>。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">那样</span>,<span style="color: black;">这般</span>写就等价于:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> A,先从A表做循环</p><span style="color: black;">select</span> * <span style="color: black;">from</span> B <span style="color: black;">where</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> A.deptId = B.deptId,再从B表做循环.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">同理,<span style="color: black;">能够</span>抽象成<span style="color: black;">这般</span>一个循环:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> List<> resultSet ;</p> <span style="color: black;">for</span>(<span style="color: black;">int</span> i=<span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;i</p> <span style="color: black;">for</span>(<span style="color: black;">int</span> j=<span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;j</p> <span style="color: black;">if</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(A.deptId==B.deptId) {</p> resultSet.<span style="color: black;">add</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(A);</p> <span style="color: black;">break</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p><span style="color: black;">数据库最费劲的<span style="color: black;">便是</span>跟程序链接释放。假设链接了两次,每次做上百万次的数据集<span style="color: black;">查找</span>,查完就走,<span style="color: black;">这般</span>就只做了两次;相反<span style="color: black;">创立</span>了上百万次链接,申请链接释放反复重复,<span style="color: black;">这般</span>系统就受不了了。</span><span style="color: black;">即 MySQL 优化原则,<span style="color: black;">便是</span>小表驱动大表,小的数据集驱动大的数据集,从而让性能更优。</span><span style="color: black;"><span style="color: black;">因此呢</span>,<span style="color: black;">咱们</span>要<span style="color: black;">选取</span>最外层循环小的,<span style="color: black;">亦</span><span style="color: black;">便是</span>,<span style="color: black;">倘若</span> B 的数据量<span style="color: black;">少于</span> A,适合<span style="color: black;">运用</span> in,<span style="color: black;">倘若</span> B 的数据量大于 A,即适合<span style="color: black;">选取</span> exist。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">21</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">尽可能</span>用 union all 替换 union</span></strong></h3><span style="color: black;"><span style="color: black;">倘若</span>检索结果中不会有重复的记录,<span style="color: black;">举荐</span> union all 替换 union。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid=<span style="color: black;">1</span><span style="color: black;">union</span><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age = <span style="color: black;">10</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid=<span style="color: black;">1</span><span style="color: black;">union</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> all </p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> age = <span style="color: black;">10</span><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;"><span style="color: black;">倘若</span><span style="color: black;">运用</span> union,不管检索结果有<span style="color: black;">无</span>重复,都会尝试进行合并,<span style="color: black;">而后</span>在输出<span style="color: black;">最后</span>结果前进行排序。</span><span style="color: black;"><span style="color: black;">倘若</span>已知检索结果<span style="color: black;">无</span>重复记录,<span style="color: black;">运用</span> union all 代替 union,<span style="color: black;">这般</span>会提<span style="color: black;">有效</span>率。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">22</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">索引不宜太多,<span style="color: black;">通常</span> 5 个以内</span></strong></h3><span style="color: black;"><span style="color: black;">原由</span>如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">索引并不是越多越好,索引虽然<span style="color: black;">加强</span>了<span style="color: black;">查找</span>的效率,<span style="color: black;">然则</span><span style="color: black;">亦</span>降低了<span style="color: black;">插进</span>和更新的效率。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">insert 或 update 时有可能会重建索引,<span style="color: black;">因此</span>建索引<span style="color: black;">必须</span><span style="color: black;">谨慎</span><span style="color: black;">思虑</span>,视<span style="color: black;">详细</span><span style="color: black;">状况</span>来定。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一个表的索引数最好不要超过 5 个,若太多<span style="color: black;">必须</span><span style="color: black;">思虑</span><span style="color: black;">有些</span>索引<span style="color: black;">是不是</span><span style="color: black;">无</span>存在的必要。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">23</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">尽可能</span><span style="color: black;">运用</span>数字型字段,若只含数值信息的字段<span style="color: black;">尽可能</span>不要设计为字符型</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p>king_id` varchar(<span style="color: black;">20</span>) NOT <span style="color: black;">NULL</span> COMMENT <span style="color: black;"><span style="color: black;">保护</span>者Id</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">`king_id`</span> <span style="color: black;">int</span>(<span style="color: black;">11</span>) NOT NULL COMMENT <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">保护</span>者Id`</p>
</span><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;">相<span style="color: black;">针对</span>数字型字段,字符型会降低<span style="color: black;">查找</span>和连接的性能,并会<span style="color: black;">增多</span>存储开销。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">24</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">索引不适合建在有<span style="color: black;">海量</span>重复数据的字段上,如性别这类型数据库字段</span></strong></h3><span style="color: black;"><span style="color: black;">由于</span> SQL 优化器是<span style="color: black;">按照</span>表中数据量来进行<span style="color: black;">查找</span>优化的,<span style="color: black;">倘若</span>索引列有<span style="color: black;">海量</span>重复数据,MySQL <span style="color: black;">查找</span>优化器推算<span style="color: black;">发掘</span>不走索引的成本更低,很可能就放弃索引了。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">25</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">尽可能</span>避免向客户端返回<span style="color: black;">太多</span>数据量</span></strong></h3><span style="color: black;">假设业务需求是,用户请求查看自己<span style="color: black;">近期</span>一年观看过的直播数据。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//一次性<span style="color: black;">查找</span>所有数据回来</p><span style="color: black;">select</span> * <span style="color: black;">from</span> LivingInfo <span style="color: black;">where</span> watchId =useId <span style="color: black;">and</span>watchTime >=<span style="color: black;">Date_sub</span>(<span style="color: black;">now</span>(),<span style="color: black;">Interval</span> <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> Y)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//分页<span style="color: black;">查找</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> LivingInfo <span style="color: black;">where</span> watchId =useId <span style="color: black;">and</span> watchTime>= <span style="color: black;">Date_sub</span>(<span style="color: black;">now</span>(),<span style="color: black;">Interval</span> <span style="color: black;">1</span> Y) <span style="color: black;">limit</span> <span style="color: black;">offset</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,pageSize</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">//<span style="color: black;">倘若</span>是前端分页,<span style="color: black;">能够</span>先<span style="color: black;">查找</span>前两百条记录,<span style="color: black;">由于</span><span style="color: black;">通常</span>用户应该<span style="color: black;">亦</span>不会往下翻太多页,</p><span style="color: black;">select</span> * <span style="color: black;">from</span> LivingInfo <span style="color: black;">where</span> watchId =useId <span style="color: black;">and</span> watchTime>= <span style="color: black;">Date_sub</span>(<span style="color: black;">now</span>(),<span style="color: black;">Interval</span> <span style="color: black;">1</span> Y) <span style="color: black;">limit</span> <span style="color: black;">200</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">26</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">当在 SQL 语句中连接多个表时,请<span style="color: black;">运用</span>表的别名,并把别名前缀于每一列上,<span style="color: black;">这般</span>语义更加清晰。</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> A <span style="color: black;">inner</span><span style="color: black;">join</span> B <span style="color: black;">on</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> A.deptId = B.deptId;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> memeber.name,deptment.deptName <span style="color: black;">from</span> A <span style="color: black;">member</span> <span style="color: black;">inner</span><span style="color: black;">join</span> B deptment <span style="color: black;">on</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">member.deptId = deptment.deptId;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">27</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;">尽可能<span style="color: black;">运用</span> varchar/nvarchar 代替 char/nchar</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p> `deptName` char(<span style="color: black;">100</span>) <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span> COMMENT <span style="color: black;"><span style="color: black;">分部</span>名<span style="color: black;">叫作</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p> `deptName` varchar(<span style="color: black;">100</span>) <span style="color: black;">DEFAULT</span> <span style="color: black;">NULL</span> COMMENT <span style="color: black;"><span style="color: black;">分部</span>名<span style="color: black;">叫作</span></span><span style="color: black;">理由如下:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">由于</span><span style="color: black;">首要</span>变长字段存储空间小,<span style="color: black;">能够</span>节省存储空间。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">其次<span style="color: black;">针对</span><span style="color: black;">查找</span><span style="color: black;">来讲</span>,在一个相对较小的字段内搜索,效率更高。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">28</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">为了<span style="color: black;">加强</span> group by 语句的效率,<span style="color: black;">能够</span>在执行到该语句前,把不<span style="color: black;">必须</span>的记录过滤掉。</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">反例:</span></p><span style="color: black;">select</span> job,<span style="color: black;">avg</span>(salary) <span style="color: black;">from</span> employee <span style="color: black;">group</span> <span style="color: black;">by</span> job <span style="color: black;">having</span>job =<span style="color: black;">president</span><span style="color: black;">or</span> job = <span style="color: black;">managent</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> job,<span style="color: black;">avg</span>(salary) <span style="color: black;">from</span> employee <span style="color: black;">where</span> job =<span style="color: black;">president</span><span style="color: black;">or</span> job = <span style="color: black;">managent</span> <span style="color: black;">group</span> <span style="color: black;">by</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> job;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">29</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">倘若</span>字段类型是字符串,where 时<span style="color: black;">必定</span>用引号括起来,否则索引失效</span></strong></h3><span style="color: black;">反例:</span><span style="color: black;">select</span>*<span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid =<span style="color: black;">123</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">正例:</span></p><span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid =<span style="color: black;">123</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><strong style="color: blue;"><span style="color: black;">理由:</span></strong><span style="color: black;"><span style="color: black;">为何</span><span style="color: black;">第1</span>条语句未加单引号就不走索引了呢?这是<span style="color: black;">由于</span>不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL 会做隐式的类型转换,把它们转换为浮点数再做比较。</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">30</strong></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">运用</span> explain 分析你 SQL 的计划</span></strong></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">平常</span><span style="color: black;">研发</span>写 SQL 的时候,<span style="color: black;">尽可能</span>养成一个习惯吧。用 explain 分析一下你写的 SQL,尤其是走不走索引这<span style="color: black;">一起</span>。</span></p><span style="color: black;">explain</span> <span style="color: black;">select</span> * <span style="color: black;">from</span> <span style="color: black;">user</span> <span style="color: black;">where</span> userid =<span style="color: black;">10086</span> <span style="color: black;">or</span> age =<span style="color: black;">18</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">作者:<span style="color: black;">Jay_huaxiao</span></span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">编辑:陶家龙</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">出处:转载自<span style="color: black;">微X</span>公众号</span><span style="color: black;">捡田螺的小男孩</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;">精彩<span style="color: black;">文案</span><span style="color: black;">举荐</span>:</strong></span></p><a style="color: black;"><span style="color: black;">讲真,应该<span style="color: black;">选取</span>RabbitMQ还是Kafka?</span></a><a style="color: black;"><span style="color: black;">阿里P9大佬:优秀工程师<span style="color: black;">必须</span>的8大能力!</span></a><a style="color: black;"><span style="color: black;">快哭了!我被同事写的代码坑惨了</span></a>
我赞同你的看法,你的智慧让人佩服,谢谢分享。 你的见解独到,让我受益匪浅,非常感谢。 期待楼主的下一次分享!” 感谢楼主的分享!我学到了很多。
页:
[1]