比较 T-SQL Between 和 '<' '>' 运算符的性能差异?
Posted
技术标签:
【中文标题】比较 T-SQL Between 和 \'<\' \'>\' 运算符的性能差异?【英文标题】:Compare performance difference of T-SQL Between and '<' '>' operator?比较 T-SQL Between 和 '<' '>' 运算符的性能差异? 【发布时间】:2009-05-28 14:56:38 【问题描述】:我尝试通过搜索引擎、MSDN 等进行搜索。但什么也做不了。抱歉,如果之前有人问过这个问题。使用 T-SQL 的“Between”关键字和使用比较运算符之间有性能差异吗?
【问题讨论】:
【参考方案1】:您可以通过在这两种情况下检查查询计划来轻松地检查这一点。我知道这没有区别。 BETWEEN 和“”之间存在逻辑差异...... BETWEEN 是包容性的。它相当于“”。
【讨论】:
【参考方案2】:查询引擎在>=
和<=
之间进行转换(查看查询计划),因此在实践中它们是相同的,理论上>= <=
更快,因为引擎不必翻译。祝你好运,但注意到不同之处。
反正我用的是 between,我觉得它读起来更容易
具有大量比较的非常复杂的查询/嵌套视图可能会从更改为 >= <=
中受益,因为这可能会通过减少重构查询所花费的时间来防止优化超时(只是一个理论,未经我测试,我从来没有注意到了)
【讨论】:
【参考方案3】:喜欢人们提供代码来进行自己的测试,但您需要进行更大的子集/重复测试以说明加载到内存中的索引等......不过,在得出结论之前。这是具有更大表和 10 次迭代的相同代码
DECLARE
@Startdatetime datetime ,
@Diff int = 0 ,
@Addrowcount int = 1000 ,
@ptr int = 1;
SET NOCOUNT ON;
--Create a tempory table to perform our tests on
DROP TABLE dbo.perftest
CREATE TABLE dbo.perftest( id int NOT NULL
IDENTITY(1 , 1)
PRIMARY KEY ,
mytext nvarchar( 50 )NOT NULL );
--Now add some sample rows
SET @Addrowcount = 20000;
WHILE(@Addrowcount > 0)
BEGIN
INSERT INTO dbo.perftest( mytext )
VALUES( 'thetext' );
SET @Addrowcount = @Addrowcount - 1;
END;
WHILE @ptr < 10 -- do this a few times to account for indexes being loaded into memory
BEGIN
SELECT @Startdatetime = GETDATE();
-- do method 1 here
SELECT mytext
FROM dbo.perftest
WHERE(id >= (100 + (@ptr * 1000)))
AND (id <= (500 + (@ptr * 1000)));
--end method1
SELECT @Diff = DATEDIFF( millisecond , @Startdatetime , GETDATE());
PRINT ':Method 1: ' + CAST(@Diff AS nvarchar( 20 )) + ' ms';
--reset start time
SELECT @Startdatetime = GETDATE();
--do method2 here
SELECT mytext
FROM dbo.perftest
WHERE id BETWEEN (300 + (@ptr * 1000))
AND (800 + (@ptr * 1000));
--end method2
SELECT @Diff = DATEDIFF( millisecond , @Startdatetime , GETDATE());
PRINT ':Method 2: ' + CAST(@Diff AS nvarchar( 20 )) + ' ms';
SET @ptr = @ptr + 1
END
给你一组非常不同的结果:
--Method 1 -- 10 ms
--Method 2 -- 33 ms
--Method 1 -- 40 ms
--Method 2 -- 26 ms
--Method 1 -- 23 ms
--Method 2 -- 23 ms
--Method 1 -- 13 ms
--Method 2 -- 16 ms
--Method 1 -- 13 ms
--Method 2 -- 20 ms
--Method 1 -- 6 ms
--Method 2 -- 16 ms
--Method 1 -- 26 ms
--Method 2 -- 16 ms
--Method 1 -- 13 ms
--Method 2 -- 13 ms
--Method 1 -- 16 ms
--Method 2 -- 13 ms
我会说从这个(仍然很不科学的)测试来看,两种方式都没有太大区别。
【讨论】:
【参考方案4】:我还对使用 (>= 和 = 样式运算符)。 这是我使用的脚本:
DECLARE
@Startdatetime datetime ,
@Diff int = 0 ,
@Addrowcount int = 1000;
SET NOCOUNT ON;
--Create a tempory table to perform our tests on
CREATE TABLE dbo.perftest( id smallint NOT NULL
IDENTITY(1 , 1)
PRIMARY KEY ,
mytext nvarchar( 50 )NOT NULL );
--Now add some sample rows
SET @Addrowcount = 1000;
WHILE(@Addrowcount > 0)
BEGIN
INSERT INTO dbo.perftest( mytext )
VALUES( 'thetext' );
SET @Addrowcount = @Addrowcount - 1;
END;
SELECT @Startdatetime = GETDATE();
-- do method 1 here
SELECT mytext
FROM dbo.perftest
WHERE(id >= 100)
AND (id <= 900);
--end method1
SELECT @Diff = DATEDIFF( millisecond , @Startdatetime , GETDATE());
PRINT ':Method 1: ' + CAST(@Diff AS nvarchar( 20 )) + ' ms';
--reset start time
SELECT @Startdatetime = GETDATE();
--do method2 here
SELECT mytext
FROM dbo.perftest
WHERE id BETWEEN 100
AND 900;
--end method2
SELECT @Diff = DATEDIFF( millisecond , @Startdatetime , GETDATE());
PRINT ':Method 2: ' + CAST(@Diff AS nvarchar( 20 )) + ' ms';
结果是:
方法 1:140 毫秒
方法 2:70 毫秒
所以看来使用 between 可以提高性能。
【讨论】:
不确定这样的测试有多有效...我想和任何简单的配置文件测试一样有效,但这并不能说明什么。基于缓存(您刚刚添加记录)以及当时没有其他事情发生(与现实世界的服务器不同)以及同时添加所有记录,而不是在多个页面/时间上被碎片化,可能会有很大不同. 运行相同的测试几百次并提供每种方法的平均时间会很有用。【参考方案5】:这里要相互比较的两个运算符根本不同,因此生成的执行计划也可能不同(尽管不能保证)。
决定因素是应用比较运算符的列的数据分布(选择性)。这与统计信息一起将决定是否使用索引等。
希望这是有道理的。
【讨论】:
不知道为什么这被否决了。约翰有没有说错话?有人感觉不是很好吗?有人有什么想法吗? 我从未更改过原始问题。我也没有投反对票。 vs = 并不是根本的区别,但这可能就是它被否决的原因。应该考虑一个小的逻辑差异,并且性能差异绝对为零。【参考方案6】:事实上。我只是尝试使用我的一些数据进行验证。 BETWEEN 等价于 ">=" 和 "
【讨论】:
不,这是不正确的。你确定你有精确到毫秒的5/30/2010 00:00:00.000
数据吗?
这与文档相矛盾,这意味着如果这是真的,那就是一个错误。我倾向于同意史密斯先生的观点,即数据可能有误。【参考方案7】:
在更复杂的查询中,您无法事先知道要与之比较的最小值或最大值,那么使用 BETWEEN 几乎等同于使用 >= 和
但是,当您事先确切知道最小值和最大值是什么时,不使用 BETWEEN 运算符而是将所需结果与最小值以下 1 个数字和最大值以上 1 个数字进行比较会更便宜。
SELECT n.Number FROM dbo.Numbers AS n
WHERE n.Number BETWEEN 1 AND 100
几乎等同于:
SELECT n.Number FROM dbo.Numbers AS n
WHERE n.Number >= 1 AND n.Number <= 100
每行分别针对 >、
宁可这样做:
SELECT n.Number FROM dbo.Numbers AS n
WHERE n.Number > 0 AND n.Number < 101
每行仅针对 > 和 <.> 进行比较
【讨论】:
以上是关于比较 T-SQL Between 和 '<' '>' 运算符的性能差异?的主要内容,如果未能解决你的问题,请参考以下文章