索引SQL表以查找最佳匹配字符串的最佳方法

时间:2016-11-01 23:21:24

标签: sql sql-server indexing

假设我有一个带有int PK列和nvarchar(max)的SQL表。在nvarchar(max)列中,我有一堆表条目,都是这样的:

SOME_PEOPLE_LIKE_APPLES
SOME_PEOPLE_LIKE_APPLES_ON_TUESDAY
SOME_PEOPLE_LIKE_APPLES_ON_THE_MOON
SOME_PEOPLE_LIKE_APPLES_ON_THE_MOON_CAFE
SOME_PEOPLE_LIKE_APPLES_ON_THE_RIVER
.
.
.
SOME_ANTS_HATE_SYRUP
SOME_ANTS_HATE_SYRUP_WITH_STRAWBERRIES

这些行中有数百万行 - 然后让我们说我的目标是找到输入searchTerm重叠最多的行 - 所以在这种情况下,如果我输入{{ 1}},返回的条目将是上表中的第三个条目SOME PEOPLE_LIKE_APPLES_ON_THE_MOON_MOUNTAIN

我有一个非常天真的SPROC,它按如下方式遍历整个表格:

SOME_PEOPLE_LIKE_APPLES_ON_THE_MOON

我然后SELECT DISTINCT phrase, len(phrase) l, [id] FROM X WHERE searchTerm LIKE phrase + '%' -- phrase is the row entry being searched against -- searchTerm is the phrase we're searching for 长度并选择仅ORDER BY

是否有办法加快速度,也许是通过做一些索引?

如果这令人困惑,请将其视为TOP

我在MSSQL 2008上如果有任何区别

2 个答案:

答案 0 :(得分:1)

如果您的NVARCHAR列上有索引,LIKE 'Something%' -search将能够使用它并且应该非常快。

如果一开始就有通配符,那你就不走运了。但是 - 在你的情况下 - 这应该工作。

您可以使用存储字符串长度的索引持久计算列。在这种情况下,您可以通过过滤掉所有短或长的字符串来极大地减少工作量。

如果搜索字词中的某些字词经常出现但不是随处可见,则可以再次使用旁边列,并像AND InlcudePEOPLE=1 AND IncludeMOON=1一样过滤

更新

这是一个例子

CREATE TABLE Phrase(ID INT IDENTITY
                   ,Phrase NVARCHAR(100)
                   ,PhraseLength AS LEN(Phrase) PERSISTED);
CREATE INDEX IX_Phrase_Phrase ON Phrase(Phrase);
CREATE INDEX IX_Phrase_PhraseLength ON Phrase(PhraseLength);

INSERT INTO Phrase
VALUES
 ('SOME_PEOPLE_LIKE_APPLES')
,('SOME_PEOPLE_LIKE_APPLES_ON_TUESDAY')
,('SOME_PEOPLE_LIKE_APPLES_ON_THE_MOON')
,('SOME_PEOPLE_LIKE_APPLES_ON_THE_MOON_CAFE')
,('SOME_PEOPLE_LIKE_APPLES_ON_THE_RIVER')
,('SOME_ANTS_HATE_SYRUP')
,('SOME_ANTS_HATE_SYRUP_WITH_STRAWBERRIES');

DECLARE @SearchTerm NVARCHAR(100)=N'SOME_PEOPLE_LIKE_APPLES_ON_THE_MOON_MOUNTAIN';

- 这使用索引(根据执行计划检查)

SELECT TOP 1 * 
FROM Phrase 
WHERE @SearchTerm LIKE Phrase + '%'
ORDER BY PhraseLength DESC;

- 这可能会更好,请检查您的高行数。

SELECT TOP 1 *
FROM Phrase
WHERE Phrase=LEFT(@SearchTerm,PhraseLength)
ORDER BY PhraseLength DESC;
GO

- 清理

DROP TABLE Phrase;

答案 1 :(得分:1)

这里最好的解决方案是创建一个全文搜索索引:

https://msdn.microsoft.com/en-us/library/ms142571.aspx

为此任务优化全文搜索,创建索引后,您可以使用带有CONTAINS全文功能的全文查询来有效地查找匹配项:

idisis=ajax.responseText;
document.getElementById(idisis).innerHTML= some text; 
// ('idisis') || (''+idisis+'')|| ("'+idisis+'") 

全文搜索不仅允许通过project => { for (let i = 0; i < project.category.length; i++) { if (project.category[i] === category) { return true; } } return false; } 等查询提示进行自定义优化,还允许在搜索字词中使用AND和OR等停用词,以及各种其他文本搜索功能,例如能够查找自动拼写相同单词的变体并按相关性过滤等。