SQL'就像'vs'='的性能
这个问题围绕着我想知道的事情,但答案并没有完全解决它。
一般来说,当使用通配符时,'='比'like'更快。 这似乎是传统的看法。 但是,假设我有一个列包含有限数量的不同的固定,硬编码,varchar标识符,我想select匹配其中之一的所有行:
select * from table where value like 'abc%'
和
select * from table where value = 'abcdefghijklmn'
“像”应该只需要testing前三个字符来查找匹配,而“=”必须比较整个string。 在这种情况下,在我看来,“喜欢”会有一个优势,其他所有的东西都是平等的。
这是作为一个普通的学术问题,所以不应该在哪个数据库中,但它是使用SQL Server 2005产生的。
见http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx
从那里引用:
LIKE的索引使用规则大致如下:
如果你的filter标准使用equals =并且该字段被索引,那么很有可能它将使用INDEX / CLUSTERED INDEX SEEK
如果你的过滤标准使用了LIKE,没有通配符(就像你在Web报表中有一个参数可以有一个%,但是你使用完整的string),那么使用这个索引大概和#1一样。 增加的成本几乎没有。
如果你的过滤标准使用了LIKE,但是在开始时使用了一个通配符(如Name0 LIKE'UTER'),那么使用该索引的可能性要小得多,但是它仍然可以至less在一个完整的或部分的范围内执行INDEX SCAN该指数。
然而,如果你的过滤标准使用LIKE,但是以STRING FIRST开头,并且在后面的通配符(如Name0 LIKE'COMP%ER')那么SQL可能只使用INDEX SEEK来快速查找具有相同的第一行开始字符,然后通过这些行查看完全匹配。
(请记住,SQL引擎仍然可能不会按照您期望的方式使用索引,具体取决于您的查询中正在进行的操作以及要join的表。SQL引擎保留重写您的权利查询一点,以它认为是最有效的方式获取数据,可能包括INDEX SCAN而不是INDEX SEEK)
这是一个可衡量的差异。
运行以下命令:
Create Table #TempTester (id int, col1 varchar(20), value varchar(20)) go INSERT INTO #TempTester (id, col1, value) VALUES (1, 'this is #1', 'abcdefghij') GO INSERT INTO #TempTester (id, col1, value) VALUES (2, 'this is #2', 'foob'), (3, 'this is #3', 'abdefghic'), (4, 'this is #4', 'other'), (5, 'this is #5', 'zyx'), (6, 'this is #6', 'zyx'), (7, 'this is #7', 'zyx'), (8, 'this is #8', 'klm'), (9, 'this is #9', 'klm'), (10, 'this is #10', 'zyx') GO 10000 CREATE CLUSTERED INDEX ixId ON #TempTester(id)CREATE CLUSTERED INDEX ixId ON #TempTester(id) CREATE NONCLUSTERED INDEX ixTesting ON #TempTester(value)
然后:
SET SHOWPLAN_XML ON
然后:
SELECT * FROM #TempTester WHERE value LIKE 'abc%' SELECT * FROM #TempTester WHERE value = 'abcdefghij'
由此产生的执行计划显示,第一个操作的成本LIKE
比较比=
比较贵10倍左右。
如果您可以使用=
比较,请这样做。
你也应该记住,使用like
,一些SQL风格将忽略索引,这将杀死性能。 如果你不像你的例子那样使用“开始”模式,情况尤其如此。
你应该真的看看查询的执行计划,看看它在做什么,尽可能less的猜测。
这就是说,“开始”模式可以在sql server中进行优化。 它将使用表索引。 EF 4.0切换到like
StartsWith
这个原因。
如果value
是未编制索引,则会导致表扫描。 这种情况下的性能差异可以忽略不计。
如果value
被索引,Daniel在他的评论中指出, =
会导致索引查找,这是O(log N)性能。 LIKE将(很可能 – 取决于它的select性)导致对索引>= 'abc'
和< 'abd'
的部分扫描,这将需要比=
更多的努力。
请注意,我在这里说的是SQL Server,并不是所有的DBMS都会喜欢LIKE。
你问的是错误的问题。 在数据库中不是操作员performance的重要问题,总是expression式的合理性,以及总体查询的可维护性 。 运营商本身的绩效在很大程度上是无关紧要的。
那么,如何比较SARG可比性? LIKE
,当与不以常量开始的expression式(例如,当使用LIKE '%something'
)一起使用时,定义为非SARGabale。 但是这样做=
或者LIKE 'something%'
SARGable? 不。与任何有关SQL性能的问题一样,答案不在于查询文本,而是在部署模式。 如果一个索引存在以满足它们,这些expression式可能是SARGable。
所以,真相被告知, =
和LIKE
之间有小的差异。 但是,询问一个操作员还是其他操作员在SQL中是否“更快”,就像是问'快点什么,一辆红色的车还是一辆蓝色的车?'。 你应该问一些关于引擎大小和车辆重量的问题,而不是关于颜色……要处理有关优化关系表的问题,需要查看的地方是WHERE子句中的索引和expression式 (以及其他子句,但通常从WHERE开始)。
一个使用mysql 5.5的个人示例:我有两个表之间的内部连接,300万行之一和10000行之一。
在下面的索引上使用类似的符号(没有通配符)时,大约需要30秒:
where login like '12345678'
使用'解释'我得到:
当在同一个查询中使用'='时,大约需要0.1秒:
where login ='600009'
使用'解释'我得到:
正如你所看到的like
,索引查找完全取消了,所以查询花费了300多倍的时间。
也许你正在寻找全文search 。
与全文search相比,LIKE Transact-SQL谓词仅适用于字符模式。 此外,您不能使用LIKE谓词来查询格式化的二进制数据。 此外,针对大量非结构化文本数据的LIKE查询比针对相同数据的等效全文查询慢得多 。 针对数百万行文本数据的LIKE查询可能需要几分钟才能返回; 而对于相同的数据,全文查询可能只需要几秒或更less的时间,具体取决于返回的行数。
首先,
他们并不总是平等的
select 'Hello' from dual where 'Hello ' like 'Hello'; select 'Hello' from dual where 'Hello ' = 'Hello';
当事情并不总是平等的时候,谈论他们的performance并不是那么相关。
如果你正在处理string和只有字符variables,那么你可以谈论性能。 但是不要使用like和“=”作为一般可互换的。
正如你在许多post(以上和其他问题)中看到的那样,在相等的情况下,由于模式匹配(整理)