Answers:
全文索引通常不是魔术,而是需要额外的维护,磁盘空间以及对查询模式的相当侵入性的更改。
除非您真正需要索引大型文档(例如电子邮件正文,PDF,Word文档等),否则它们会过大(如果说实话,我会完全从SQL Server中删除该过程,并且使用Elasticsearch或类似的东西)。
对于较小的用例,计算列通常是一种更好的方法。
这是一个快速的演示设置:
use tempdb
CREATE TABLE #fulltextindexesarestupid (Id INT PRIMARY KEY CLUSTERED, StopAbusingFeatures VARCHAR(100))
INSERT #fulltextindexesarestupid (Id)
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY (@@ROWCOUNT))
FROM sys.messages AS m
CROSS JOIN sys.messages AS m2
UPDATE #fulltextindexesarestupid
SET StopAbusingFeatures = CASE WHEN Id % 15 = 0 THEN 'Bad'
WHEN Id % 3 = 0 THEN 'Idea'
WHEN Id % 5 = 0 THEN 'Jeans'
END
ALTER TABLE #fulltextindexesarestupid
ADD LessBad AS CONVERT(BIT, CASE WHEN StopAbusingFeatures LIKE '%Bad%' THEN 1
WHEN StopAbusingFeatures LIKE '%Idea%' THEN 1
ELSE 0 END)
CREATE UNIQUE NONCLUSTERED INDEX ix_whatever ON #fulltextindexesarestupid (LessBad, Id)
即使是基于非持久性列的查询,也为我们提供了一个“使用索引”的计划:
SELECT COUNT(*)
FROM #fulltextindexesarestupid AS f
WHERE LessBad = 1
sp_BlitzErik的答案在很多方面都很有帮助,但是我不认为这就是为什么您不应该使用全文搜索的原因。全文搜索无法满足您的要求。不能搜索多个字段。它在那里可以矢量化单词内容,并使用字典,存根,词法分析器,地名词典,停用词消除功能以及许多其他技巧,这些技巧都不适用。或者,尚未显示适用。
我也不同意该解决方案,尽管我不确定如何在SQL Server中更好地做到这一点。让我们为PostgreSQL重新创建他的数据-在PostgreSQL中创建也要干净得多。
CREATE TABLE fulltextindexesarestupid
AS
SELECT
id,
CASE WHEN Id % 15 = 0 THEN 'Bad'
WHEN Id % 3 = 0 THEN 'Idea'
WHEN Id % 5 = 0 THEN 'Jeans'
END AS StopAbusingFeatures
FROM generate_series(1,1000000) AS id;
现在您想要的是一个枚举类型,
CREATE TYPE foo AS ENUM ('Bad', 'Idea', 'Jeans');
ALTER TABLE fulltextindexesarestupid
ALTER StopAbusingFeatures
SET DATA TYPE foo
USING StopAbusingFeatures::foo;
现在,您已经将字符串折叠为整数表示形式。但更好的是,您可以像以前一样查询它们。
SELECT *
FROM fulltextindexesarestupid
WHERE StopAbusingFeatures = 'Bad';
这具有效果。
没有这些好处,您实际上只是在尝试优化字符串比较。但可惜的是,鉴于建议中的代码,我什至不确定sp_BlitzErik如何获得答案,
like '%rock%' or
like '%paper%' or
like '%scisor%' or
like '%car%' or
like '%pasta%'
您可以使用枚举或sp_BlitzErik建议的手动滚动方法将标记折叠为整数,但是如果可以折叠,为什么还要像未锚定的那样折叠?即,如果您知道'%pasta%'是令牌'pasta',那么为什么要%
在其两面都使用。如果没有'%',则将执行相等性检查,并且即使是文本也应该很快。