我有一个场景,我需要执行以下操作:
SELECT *
FROM
[dbo].[MyTable]
WHERE
[Url] LIKE '%<some url>%';
我必须在Url('%<some url>%'
)的开头和结尾使用两个%(通配符),因为用户应该能够搜索完整的URL,即使他键入了部分文本。例如,如果网址为http://www.google.co.in且用户输入“goo”,则网址必须出现在搜索结果中。 LIKE
运算符导致性能问题。 我需要一个替代,以便我可以摆脱这个声明和通配符。换句话说,我不想在这种情况下使用LIKE语句。我尝试使用T-SQL CONTAINS
,但它没有解决我的问题。除了可以执行模式匹配并快速提供结果之外,还有其他可用选择吗?
答案 0 :(得分:8)
使用%开始使用会导致扫描。没有绕过它。它必须评估每个价值。
如果您为列编制索引,则应该是索引(而不是表格)扫描。
您没有其他不会导致扫描的选择 Charindex和patindex是替代品,但仍会扫描而不能解决性能问题。
你能将组件拆分成一个单独的表吗?
WWW
谷歌
合作
在
然后搜索类似&#39; goo%&#39;? 这将使用索引,因为它不以%。
开头更好的是,你可以搜索谷歌&#39;并获得索引搜索。
并且您希望该表中的字符串是唯一的,在Int PK上具有单独的连接,因此它不会返回多个www。
怀疑FullText Contains并不快,因为FullText将URL保留为一个单词。
答案 1 :(得分:1)
据我所知,除了like
或contains
(全文搜索功能)之外别无选择,可以提供更好的性能。
您可以做的是尝试通过优化查询来提高性能。
要做到这一点,您需要了解一下您的用户和他们将如何使用您的系统。
我怀疑大多数人会从地址的开头输入一个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) > 0
与url like '%oogl%'
的作用相同,但在内部它们的工作方式不同。对于某些人来说,LIKE表达式更快,对于其他人来说,CHARINDEX方法更快。也许这取决于查询,处理器数量,操作系统等等。值得一试。