简体   繁体   English

在SQL Server中选择LIKE'%string%',而不使用FULL-TEXT-SEARCH

[英]Select LIKE '%string%', without FULL-TEXT-SEARCH in SQL Server

-- create table
CREATE TABLE dbo.Tests
(
    Id BIGINT NOT NULL IDENTITY,
    String NVARCHAR(100),
    StringReversed AS REVERSE(String),
    CONSTRAINT PK_Tests PRIMARY KEY (Id), 
)
CREATE NONCLUSTERED INDEX IX1 ON dbo.Tests(String)
CREATE NONCLUSTERED INDEX IX2 ON dbo.Tests(StringReversed)


-- populate table with 100k random strings (for testing)
DECLARE @I INT = 100000
WHILE @I > 0
BEGIN
    INSERT INTO Tests(String)
    SELECT CONVERT(varchar(36), NEWID())
    SET @I = @I - 1
END

-- how do i do a LIKE '%STRING%' search which uses the index?
SELECT String, StringReversed FROM Tests WHERE String LIKE '%0A7EB%'

SELECT String, StringReversed FROM Tests 
    WHERE String LIKE '0A7EB%' OR StringReversed LIKE 'BE7A0%'

Can you help me with this? 你能帮我吗? I am trying to implement a full-text-search alternative to be able to do a LIKE '%STRING%' WHERE clause. 我正在尝试实现全文搜索替代方案,以便能够执行类似'%STRING%'的WHERE子句。

I'm stuck not quite sure if this is even possible to implement? 我还不确定这是否有可能实现? Let's just assume that FULL TEXT SEARCH is not possible, and I need to use index. 让我们假设不可能进行全文搜索,而我需要使用索引。

This is a prod issue and we need to do a LIKE '%search%' in the string column. 这是一个问题,我们需要在字符串列中执行类似'%search%'的操作。 I just read here: SQL Server: Index columns used in like? 我只是在这里读到: SQL Server:索引列用在什么地方? that we can do a reverse? 我们可以逆转吗?

Hope you can help me, thanks a lot. 希望你能帮助我,非常感谢。

在此处输入图片说明

Update: I tried the string fragments approach. 更新:我尝试了字符串片段方法。

-- create table
CREATE TABLE dbo.Tests
(
    Id BIGINT NOT NULL IDENTITY,
    String NVARCHAR(100),
    CONSTRAINT PK_Tests PRIMARY KEY (Id), 
)
GO

-- create table for Test String Fragments
CREATE TABLE dbo.TestStringFragments(
    Id BIGINT NOT NULL IDENTITY,
    TestId BIGINT NOT NULL,
    Fragment NVARCHAR(100),
    CONSTRAINT PK_TestStringFragments PRIMARY KEY (Id)
)
CREATE NONCLUSTERED INDEX IX_TestStringFragments_Fragment ON dbo.TestStringFragments(Fragment)
CREATE NONCLUSTERED INDEX IX_TestStringFragments_TestId ON dbo.TestStringFragments(TestId)
GO

-- create UDF to generate string fragments
CREATE FUNCTION dbo.CreateStringFragments(@input nvarchar(100))
RETURNS TABLE WITH SCHEMABINDING
AS
RETURN 
(
    WITH x(x) AS 
    (SELECT 1 UNION ALL SELECT x+1 FROM x WHERE x < (LEN(@input)))
    SELECT Fragment = SUBSTRING(@input, x, LEN(@input)) FROM x
)
GO

-- create trigger for the Tests table
CREATE TRIGGER dbo.Tests_MaintainStringFragments
ON dbo.Tests
FOR INSERT, UPDATE, DELETE
AS
BEGIN
    SET NOCOUNT ON

    DELETE TSF FROM dbo.TestStringFragments AS TSF
    INNER JOIN deleted ON TSF.TestId = deleted.Id

    INSERT dbo.TestStringFragments(TestId, Fragment)
    SELECT inserted.Id, fragments.Fragment
    FROM inserted 
    CROSS APPLY dbo.CreateStringFragments(inserted.String) AS fragments

END
GO

-- populate table with 100k random strings (for testing)
DECLARE @I INT = 100000
WHILE @I > 0
BEGIN
    INSERT INTO Tests(String)
    SELECT CONVERT(varchar(36), NEWID())
    SET @I = @I - 1
END

Able to replicate the LIKE '%string%' code via the fragments table. 能够通过片段表复制LIKE'%string%'代码。

SELECT T.* FROM Tests T WITH(NOLOCK)
WHERE T.String LIKE '%CBB2%'

SELECT T.* FROM Tests T WITH(NOLOCK)
INNER JOIN TestStringFragments TSF WITH(NOLOCK) ON T.Id = TSF.TestId
where TSF.Fragment LIKE 'CBB2%'

My new execution plan is 61% for the first query, 39% for the second one. 我的新执行计划是第一个查询为61%,第二个查询为39%。 I'll check the trigrams approach. 我将检查trigrams方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM