我有一个表,主键由两个32位整数组成。我想通过这些明确的列表进行过滤,并希望了解最快的方法。我有三种方法可以考虑。
我的问题只是:第二种方法或第三种方法中哪种方法最快?
第一种方法我不想使用,因为如果我要列出很多(在这个例子中仅过滤2行),它会变得混乱,或者需要临时表,所以不简洁:
select *
from [table]
where
(
([int1] = 123 and [int2] = 456)
OR ([int1] = 654 and [int2] = 321)
--etc
)
第二种方法转换为varchar
select *
from [table]
where convert(varchar(10), [int1]) + ',' + convert(varchar(10), [int2]) IN ('123,456','654,321')
第三种方法将两个32位整数组合成单个64位整数
select *
from [table]
where convert(bigint, [int1]) * 4294967296 + [int2] IN (528280977864,2808908611905)
修改 感谢Aron的建议,我尝试过使用统计数据 - 这些是带有>的表格上的结果。 100万行,平均每次10次试验:
Time Statistics method 1 method 2 method 3
Client processing time 22.1 2.7 2.9
Total execution time 300.5 1099.8 1317.3
Wait time on server replies 278.4 1097.1 1314.4
所以真正查询它们是迄今为止最快的,但如果我确实在第二种或第三种方法之间进行选择,那么varchar会更快(这让我感到惊讶)。
答案 0 :(得分:1)
也许你需要提供一个更好的例子?
我尝试了你的例子,性能看起来很不错。更大数量的结果集可以更好地预测?尝试使用估计的计划。
create table #table (int1 int,int2 int)
insert into #table values(123,456);
insert into #table values(654,321);
select *
from #table
where
(
([int1] = 123 and [int2] = 456)
OR ([int1] = 654 and [int2] = 321)
)
select *
from #table
where convert(varchar(10), [int1]) +'-'+ convert(varchar(10), [int2]) IN ('123-456','654-321')
select *
from #table
where convert(bigint, [int1]) * 4294967296 + [int2] IN (528280977864,2808908611905)
--drop table #table
将给出几乎相同的估计成本。每个查询33%......
答案 1 :(得分:1)
你的第一种方法:
select *
from [table]
where ([int1] = 123 and [int2] = 456) OR
[int1] = 654 and [int2] = 321) OR
--etc
)
应该是最快的,因为它可以利用(int1, int2)
上的索引。对于大型列表而言,最快的方法可能是将对存储在具有int1
和int2
上的索引(聚簇或非聚簇)的临时表中。
我会回避玩弄价值观。查询的大部分工作是读取数据页面。比较逻辑中的轻微变化对查询几乎没有影响。
答案 2 :(得分:0)
你不想使用的第一种方法,因为它的混乱,似乎是最快的方法,只需将它们放在两列并索引它们。 SQL中的查询速度并不取决于查询的字段数或查询的复杂程度,而只取决于您使用索引的方式。