ThinkPHP 的搜索速度优化– paginate 传 total 避免重复 COUNT
MySQL 查询层面 — 用 EXPLAIN 的估算行数替代精确 COUNT
当前即使命中 keywords 缓存,分页时 paginate() 内部还会再 COUNT 一次。ThinkPHP 5.1 的 paginate 方法默认会执行 SELECT COUNT(*),这意味着你缓存了第一次 COUNT,但分页器又触发了一次。
解决方案: 对于已知总数的场景,直接告诉分页器总数:
// Search.php index() 中,paginate 改为手动传入 total
$list = db('resources')
->field('id,hashid,title,content,time,size,class')
->whereRaw(<span class="katex"><span class="katex-mathml"><math xmlns="__URL_1__"><semantics><mrow><mi>w</mi><mi>h</mi><mi>e</mi><mi>r</mi><mi>e</mi><mi>F</mi><mi>u</mi><mi>l</mi><mi>l</mi><mi>t</mi><mi>e</mi><mi>x</mi><mi>t</mi><msup><mo stretchy="false">[</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mi>s</mi><mi>q</mi><msup><mi>l</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">]</mo><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">whereFulltext['sql'],</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0019em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">t</span><span class="mopen"><span class="mopen">[</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7519em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7519em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mclose">]</span><span class="mpunct">,</span></span></span></span>whereFulltext['bind'])
->where($applyFilters)
->order('time ' . $orderDir)
->paginate(15, false, [
'query' => request()->get(),
'total' => $count, // 🔑 直接用已有 count,避免 paginate 再 COUNT 一次
]);
⚠️ ThinkPHP 最隐蔽性能杀手—— paginate() 在没有传入 total 时,会独立再执行一次 COUNT(*)。ThinkPHP 5.1 的 paginate() 在没有传入 total 参数时,会执行 SELECT count(*) FROM (你的查询) AS sub。对于 FULLTEXT 搜索来说,这意味着 每次分页查询实际上执行了两次 FULLTEXT 索引扫描——你之前已经显式 COUNT 了一次,分页器又偷偷 COUNT 了一次。现在彻底消除这种浪费。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
TP源码网 » ThinkPHP 的搜索速度优化– paginate 传 total 避免重复 COUNT
TP源码网 » ThinkPHP 的搜索速度优化– paginate 传 total 避免重复 COUNT
