You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化基于搜索关键词提取高亮文本摘要的PHP函数性能

搜索摘要提取与高亮功能优化方案

一、MySQL层处理方案(优先推荐,适合大批量数据场景)

直接在数据库层完成匹配、摘要截取逻辑,避免将全量text字段拉取到PHP侧,大幅减少网络IO和PHP内存开销,单请求处理数千条数据的效率提升非常明显:

SELECT 
    -- 其他业务字段按需添加
    id,
    -- 计算关键词首次出现的位置(不区分大小写)
    @match_pos := IF(LOCATE(LOWER(:search_key), LOWER(text_content)) = 0, 1, LOCATE(LOWER(:search_key), LOWER(text_content))) AS match_pos,
    @search_len := CHAR_LENGTH(:search_key) AS search_len,
    @text_len := CHAR_LENGTH(text_content) AS text_len,
    -- 直接生成带前后缀的摘要
    CONCAT(
        IF(@match_pos > 100, '...', ''),
        SUBSTRING(text_content, IF(@match_pos > 100, @match_pos - 100, 1), @search_len + 200),
        IF(@match_pos < @text_len - 100 - @search_len, '...', '')
    ) AS excerpt
FROM your_table
-- 前置过滤掉不包含关键词的行,减少后续处理量
WHERE LOWER(text_content) LIKE CONCAT('%', LOWER(:search_key), '%')
  • 如果你的MySQL版本>=5.7,可给text字段建立全文索引,用MATCH() AGAINST()替代LIKE做匹配,检索性能还能再提升5~10倍。
  • 高亮逻辑如果要在MySQL层实现,可以自定义UDF函数,对性能要求极高的场景可以考虑。

二、PHP层现有代码优化(无需修改SQL逻辑的场景)

现有代码可优化冗余计算、替换更高性能的字符串处理函数,整体性能可提升30%以上:

function substrExcerpt(string $search, string $text): string
{
    $search = trim($search);
    // 空关键词直接返回前200字摘要
    if ($search === '') {
        return htmlspecialchars(mb_substr($text, 0, 200) . (mb_strlen($text) > 200 ? '...' : ''), ENT_QUOTES);
    }

    $pos = mb_stripos($text, $search);
    $searchLength = mb_strlen($search);
    $textLength = mb_strlen($text);

    // 无匹配返回前200字
    if ($pos === false) {
        $excerpt = mb_substr($text, 0, 200) . ($textLength > 200 ? '...' : '');
    } else {
        if ($textLength < $searchLength + 200) {
            $excerpt = $text;
        } else {
            $start = max(0, $pos - 100);
            $prefix = $start > 0 ? '...' : '';
            $suffix = ($pos + $searchLength + 100) < $textLength ? '...' : '';
            $excerpt = $prefix . mb_substr($text, $start, $searchLength + 200) . $suffix;
        }
    }

    // 用str_ireplace替代正则替换,减少不必要的正则解析开销
    $escapedExcerpt = htmlspecialchars($excerpt, ENT_QUOTES);
    $escapedSearch = htmlspecialchars($search, ENT_QUOTES);
    return str_ireplace($escapedSearch, "<b>{$escapedSearch}</b>", $escapedExcerpt);
}
  • 批量处理场景可提前把关键词转义好,不用每次在函数内重复转义,进一步减少计算量。

三、成熟现成方案参考

  • 数据量>10万、搜索请求量高的场景,可部署Elasticsearch/OpenSearch,内置了经过工业级优化的摘要提取、关键词高亮能力,性能是自建逻辑的数倍。
  • 不想额外部署服务的场景,可直接使用PHP轻量检索库teamtnt/tntsearch,纯PHP实现无额外依赖,内置了完整的关键词匹配、摘要提取、高亮功能,开箱即用。

内容的提问来源于stack exchange,提问作者shock_gone_wild

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:27:02