使用全文索引进行查询优化

  • 时间:2025-12-06 22:55 作者: 来源: 阅读:0
  • 扫一扫,手机访问
摘要:业务系统中有个日志表,数据量每月百万条,每条数据包括三个大文本字段,类型为varchar(max),存放的是输入输出的报文数据,常常需要通过全匹配进行内容查询,也即是使用LIKE '%...%'。在文本内容较多的情况下,查询速度较慢,几十秒甚至几分钟都有可能。我一直在思考是否引入ES等搜索引擎工具,但是改动实在较大,有点小题大做了。老规矩,遇事不决问AI。AI给出了几种方案,最优解

业务系统中有个日志表,数据量每月百万条,每条数据包括三个大文本字段,类型为varchar(max),存放的是输入输出的报文数据,常常需要通过全匹配进行内容查询,也即是使用LIKE '%...%'。在文本内容较多的情况下,查询速度较慢,几十秒甚至几分钟都有可能。我一直在思考是否引入ES等搜索引擎工具,但是改动实在较大,有点小题大做了。老规矩,遇事不决问AI。

AI给出了几种方案,最优解应该是用全文索引。

步骤 1:创建全文目录(Full-Text Catalog)

全文目录是全文索引的容器,一个数据库可以有多个目录,一般创建一个默认目录即可:

-- 创建全文目录(若不存在)
IF NOT EXISTS (SELECT * FROM sys.fulltext_catalogs WHERE name = 'ftCatalog')
BEGIN
    CREATE FULLTEXT CATALOG ftCatalog 
    WITH ACCENT_SENSITIVITY = OFF -- 不区分重音(根据需求调整)
    AS DEFAULT; -- 设置为默认目录,后续创建索引可省略目录名
END

步骤 2:为表和字段创建全文索引

全文索引必须依赖表的唯一索引(一般是主键索引),且一次可针对多个字段创建:

-- 为 s_esb_log 表创建全文索引
IF NOT EXISTS (SELECT * FROM sys.fulltext_indexes WHERE object_id = OBJECT_ID('s_esb_log'))
BEGIN
    CREATE FULLTEXT INDEX ON s_esb_log (
    msg LANGUAGE 0,  -- 0 = 非特定语言,减少分词拆分
    sendmsg LANGUAGE 0,
    remark LANGUAGE 0
)
    KEY INDEX PK__s_esb_lo__3213E83F34120548 -- 依赖主键索引(需替换为实际主键索引名)
    -- 若已设置默认目录,可省略 ON ftCatalog
    WITH (
        CHANGE_TRACKING = AUTO -- 自动跟踪数据变更(增删改后自动更新索引)
    );
END

“LANGUAGE 0“这个是重点,如果不加这个,查询时使用英文或数字组合会查不到数据。

步骤 3:修改Java后端MyBatis配置文件中的查询语句

业务系统是采用SSM框架开发,需要修改框架中对应的MyBatis配置文件:

//AND msg like '%${msg}%'
AND CONTAINS(msg, '"${msg}"')

如上所示,将like语句改为CONTAINS语句。

改完重启并测试,发现根本查不到数据。

不要慌,系统在创建索引,100多G的表,创建索引要个把小时,不要像我当时一样,又不停的在找缘由,差点以为找错了方案。

索引创建好,重新在前端测试,查询速度基本达到秒级,客户再也不用盯着页面等半天了。

  • 全部评论(0)
手机二维码手机访问领取大礼包
返回顶部