使用 String.IndexOf 或 MS SQL 进行快速全文搜索

我有一个情况,我需要一个超快速的全文通配符搜索。


以前,我只使用SQL存储过程,该过程将对具有多个联接的表执行搜索,并使用查询,但是对于几百万条记录,它非常慢。LIKE '%searchTerm%'


我尝试过在SQL中进行全文索引和搜索,但是,这似乎不起作用,因为它会在单词上中断,但我需要搜索字符串的中间。


更改为一个新的 SQL 存储过程,该过程将所有搜索字段连接成一个字符串,并使用对象 ID 的另一列返回该字符串 - 然后将整个对象作为 C# 中的 a 缓存(特别是作为 C# 中的静态对象),并使用检查搜索字符串的逻辑似乎大大提高了性能(从大约 10 秒增加到大约 100 毫秒)。List<>AppPoolIndexOf()


我担心的是,这是否是一个糟糕的方法,或者是否有更好的方法?


创建要与对象 ID 关联的搜索字符串的新 SQL 存储过程如下所示:


CREATE PROCEDURE [dbo].[Search_GetLookupTable]

AS

BEGIN


    SELECT

        ObjectId,

        (Name + ' ' + OtherName + ' ' + ep.SomethingElse + ISNULL(


            (


            SELECT

                    ' ' + twl.SomeBindingName

                FROM

                    TableWithLotsOfBindings twl

                WHERE 

                    twl.ObjectId = e.ObjectId

                FOR XML PATH('')


            )


        , '')) AS SearchString,

        ep.LastActionDateTime AS OrderDate

    FROM

        ObjectTable e

        INNER JOIN ObjectMetaData ep ON ep.ObjectId = e.ObjectId

END 

GO

然后,这会被加载到具有 and 的模型中。然后,我将它保存到搜索中的属性中,然后跟踪上次加载并每隔10分钟左右回收一次。List<>ObjectIdSearchStringstaticclassDateTime


我最初也将其保存到分布式内存中缓存中,但是,性能非常差,序列化和传输数据。


private static readonly List<GlobalSearchLookupModel> _CachedSearchLookupModel = new List<GlobalSearchLookupModel>();

private static DateTime _CacheSearchLookupModelDateTime = DateTime.MinValue;


List<GlobalSearchLookupModel> lookupModels = _CachedSearchLookupModel.Value;


if (lookupModels == null)

{

   lookupModels = SqlClass.SearchLookupTable();

   _CachedSearchLookupModel.Value.Clear();

   _CachedSearchLookupModel.Value.AddRange(lookupModels);

   _CachedSearchLookupModelDateTime = DateTime.UtcNow;

}



蝴蝶不菲
浏览 137回答 2
2回答

郎朗坤

据我所知,在任何现代SQL数据库中都没有这样的解决方案。它们根本不是为像您这样的用例而设计的。对于这样的解决方案,你真的需要看看像弹性搜索或Azure搜索这样的解决方案,即使是那些需要你使用特殊构造和过滤器来实现纯通配符搜索功能的解决方案。

HUX布斯

您可以尝试使用以下想法在SQL中构建自己的searchindex:假设您的表是MyTable(Id bigint Primary Key, Text nvarchar(max)),其中是要在其中搜索的列。Text然后构建一个表IndexTable(TextIndex nvarchar(max) Primary Key, Id bigint),外键为 。IdMyTable现在,您可以使用 MyTable 中包含的文本的所有后缀填充该表。现在可以重写查询SELECT *&nbsp;FROM MyTable&nbsp;WHERE Text LIKE '%searchTerm%'toSELECT *&nbsp;FROM MyTable&nbsp;WHERE Id IN (SELECT Id FROM IndexTable WHERE TextIndex LIKE 'searchTerm%')(此查询也可以使用联接编写,但随后可能会导致重复)这应该是一个有效的查询,因为可以使用索引表的PK索引。LIKE 'searchTerm%'最后要注意的是,您可以使用触发器使该表保持最新状态。
打开App,查看更多内容
随时随地看视频慕课网APP