SQL WHERE过滤两个整数,转换为char或组合整数会更快吗?

时间:2017-06-22 01:09:32

标签: sql sql-server

我有一个表,主键由两个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会更快(这让我感到惊讶)。

3 个答案:

答案 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%......

enter image description here

答案 1 :(得分:1)

你的第一种方法:

select *
from [table]
where ([int1] = 123 and [int2] = 456) OR
       [int1] = 654 and [int2] = 321) OR
        --etc
      )

应该是最快的,因为它可以利用(int1, int2)上的索引。对于大型列表而言,最快的方法可能是将对存储在具有int1int2上的索引(聚簇或非聚簇)的临时表中。

我会回避玩弄价值观。查询的大部分工作是读取数据页面。比较逻辑中的轻微变化对查询几乎没有影响。

答案 2 :(得分:0)

你不想使用的第一种方法,因为它的混乱,似乎是最快的方法,只需将它们放在两列并索引它们。   SQL中的查询速度并不取决于查询的字段数或查询的复杂程度,而只取决于您使用索引的方式。