是否有替代T-SQL中的LIKE语句?

时间:2014-10-22 11:54:12

标签: sql sql-server tsql contains sql-like

我有一个场景,我需要执行以下操作:

SELECT *
FROM
[dbo].[MyTable]
WHERE
[Url] LIKE '%<some url>%';

我必须在Url('%<some url>%')的开头和结尾使用两个%(通配符),因为用户应该能够搜索完整的URL,即使他键入了部分文本。例如,如果网址为http://www.google.co.in且用户输入“goo”,则网址必须出现在搜索结果中。 LIKE运算符导致性能问题。 我需要一个替代,以便我可以摆脱这个声明和通配符。换句话说,我不想在这种情况下使用LIKE语句。我尝试使用T-SQL CONTAINS,但它没有解决我的问题。除了可以执行模式匹配并快速提供结果之外,还有其他可用选择吗?

5 个答案:

答案 0 :(得分:8)

使用%开始使用会导致扫描。没有绕过它。它必须评估每个价值。

如果您为列编制索引,则应该是索引(而不是表格)扫描。

您没有其他不会导致扫描的选择 Charindex和patindex是替代品,但仍会扫描而不能解决性能问题。

你能将组件拆分成一个单独的表吗? WWW
谷歌
合作

然后搜索类似&#39; goo%&#39;? 这将使用索引,因为它不以%。

开头

更好的是,你可以搜索谷歌&#39;并获得索引搜索。

并且您希望该表中的字符串是唯一的,在Int PK上具有单独的连接,因此它不会返回多个www。

怀疑FullText Contains并不快,因为FullText将URL保留为一个单词。

答案 1 :(得分:1)

据我所知,除了likecontains(全文搜索功能)之外别无选择,可以提供更好的性能。 您可以做的是尝试通过优化查询来提高性能。 要做到这一点,您需要了解一下您的用户和他们将如何使用您的系统。 我怀疑大多数人会从地址的开头输入一个URL(即没有协议),所以你可以这样做:

declare @searchTerm nvarchar(128) = 'goo'
set @searchTerm = coalesce(replace(@searchTerm ,'''',''''''),'')
select @searchTerm

SELECT *
FROM [dbo].[MyTable]
WHERE [Url] LIKE 'http://' + @searchTerm + '%'
or [Url] LIKE 'https://' + @searchTerm + '%'
or [Url] LIKE 'http://www.' + @searchTerm + '%'
or [Url] LIKE 'https://www.' + @searchTerm + '%'
or [Url] LIKE '%' + @searchTerm + '%'
option (fast 1); --get back the first result asap; 

然后给你一些优化;即,如果URL http://www.google.com可以使用url列上的索引,因为http://www.goo位于字符串的开头。 最后的option (fast 1)部分可以确保获得这种好处;由于上一个URL like %searchTerm%无法使用索引,因此我们应尽快返回响应,而不是等待缓慢的部分完成。 考虑其他常见的使用模式和方法。

答案 2 :(得分:0)

正如所写,您的查询无法进一步优化,并且无法绕过LIKE进行搜索。要提高性能,唯一可以做的就是减少SELECT只返回所需的列(如果不需要所有列),并在URL上创建包含这些列的索引。 LIKE将无法使用索引进行搜索,但扫描的数据大小减小可能会有所帮助。如果您有支持压缩的SQL Server版本,那么这也会有所帮助。

例如,如果您确实只需要A列,请写

SELECT A FROM [dbo].[MyTable] WHERE [Url] LIKE '%<some url>%';

并将索引创建为

CREATE INDEX IX_MyTable_URL 
ON MyTable([Url]) 
INCLUDE (A) WITH (DATA_COMPRESSION = PAGE);

如果您的主键中已包含A,则不必包含INCLUDE。

答案 3 :(得分:0)

您可以创建FULLTEXT索引。

首先创建目录:

CREATE FULLTEXT CATALOG ft AS DEFAULT;

现在假设您的表名为MyTable,该列为TextColumn,并且其上有一个名为UX_MyTable_TextColumn的唯一索引:

CREATE FULLTEXT INDEX ON [dbo].[MyTable](TextColumn) 
    KEY INDEX UX_MyTable_TextColumn

现在您可以使用CONTAINS搜索表格了:

SELECT *
FROM MyTable
WHERE CONTAINS(TextColumn, 'searchterm')

答案 4 :(得分:0)

您的查询非常简单,我认为没有理由这么慢。 dbms将读取记录和比较字符串的记录。通常它甚至可以在并行线程中执行此操作。

您认为您的陈述如此缓慢的原因是什么?你的桌子上有数十亿的记录吗?您的记录是否包含如此多的数据?

您最好的选择不是关心查询,而是关心数据库和系统。其他人已经在url列上建议了索引,因此可以扫描索引而不是扫描表。是否错误地设置了最大并行度?你的桌子是否支离破碎?你的硬件适合吗?这些是这里要考虑的事情。

但是:charindex('oogl', url) > 0url like '%oogl%'的作用相同,但在内部它们的工作方式不同。对于某些人来说,LIKE表达式更快,对于其他人来说,CHARINDEX方法更快。也许这取决于查询,处理器数量,操作系统等等。值得一试。