范围上的快速SQL查询

时间:2011-10-24 13:00:53

标签: sql range

我有一张IP范围表以及拥有该IP范围的各自城市和国家/地区。 IP表示为bigint(请参阅下面的等式,将IP转换为bigint),我正在做一个选择以撤回使用网站的城市/国家/地区。

将IP转换为数字的公式为

Bigint = (octet1 * (2^24)) + (octet2 * (2^16)) + (octet3 * (2^8)) + Octet 4

我的选择如下所示。在任何一种情况下,当我有很多IP地址(200)要查找时,where子句可能会变得很长,结果需要几分钟才能返回。我确实将startipnumendipnum编入索引作为聚簇索引。该表有625万行数据(IP范围和国家/地区)。有更好的方法来返回数据吗?

SELECT [startIpNum] ,[endIpNum],[country],[region],[city],[postal_code]
              ,[latitude],[longitude],[metroCode],[areacode] 
FROM [GeoLocationView] 
WHERE
    (30072067 between startipNum and endipnum) 
    OR
    (30072069 between startipNum and endipnum)

SELECT [startIpNum] ,[endIpNum],[country],[region],[city],[postal_code]
              ,[latitude],[longitude],[metroCode],[areacode] 
FROM [GeoLocationView] 
WHERE
     (startipNum <= 30072067 and 30072067 <= endipnum) or 
     (startipNum <= 30072069 and 30072069 <= endipnum)

3 个答案:

答案 0 :(得分:0)

您的群集会有所帮助。

我会选择x > ? order by x

where子句可以是来自单独表格的子选择,如下所示:

where key exists(select * from key_table)

但你必须维护这个key_table ......

当它尝试优化您的查询时 - 表查找更好地为RDMS引擎提供服务,而不是按键尾部

答案 1 :(得分:0)

可能有趣的是尝试将表变量(或临时表)与IP列表一起使用,并加入查找表

declare @ips table (ip bigint)

insert @ips (ip) values (30072067) -- etc...

SELECT <field list>
  FROM [GeoLocationView]
    inner join @ips as ips
      on ((GeoLocationView.startipNum <= ip) and (GeoLocationView.endipnum) >= ip)

答案 2 :(得分:0)

当你必须匹配很多值时,OR子句通常比临时表上的JOIN慢。