将起始IP和结束IP作为IP地址介于两者之间的范围返回记录?

时间:2015-12-12 22:42:09

标签: sql ip-address

我有大约550万条包含IP地址信息的记录。该表具有每个记录的低端和高端。我们将此范围称为ip=strdup(data[1]); name=strdup(data[0]); ip_start。这是混合的IPv4和IPv6地址。

我需要做的是找到一个单一记录,其中任何给定的IP地址落在开始和结束范围之间。

即使只考虑IPv4地址,在转换传入的IP地址以及开始和结束范围时,运行找到的函数here也需要整整58秒才能运行。这显然是不可接受的。

我可以在C#中做到这一点,但老实说,我认为SQL会更快,因为我使用的是实体框架而且我将通过WCF进行网络调用...我投掷的次数越少电线,越多越好。

我考虑过使用之前提供的链接中的函数运行转换,并且有两个索引ip_end列但是......我将使用IPv6地址做什么?显然我不能以同样的方式转换它们,因为IPv6地址中的空白部分实际上是空的,而你有一个奇怪的类似的#34;在IPv4中为0。

有没有人有任何建议或地方可以看?

仅为了参考,链接提及给我们以下功能:

bigint

1 个答案:

答案 0 :(得分:1)

这是一种策略而不是确切的代码。

首先,更新您的表以获得整数ips。代码不适用于字符串表示。这是一种方法:

alter table t add ipstart_int unsigned;
alter table t add ipend_int unsigned;

update t
    set ipstart_int = dbo.IPAddressToInteger(ipstart),
        ipend_int = dbo.IPAddressToInteger(ipend);

然后在ipstart_int, ipend_int上创建适当的索引。

然后,通过执行以下操作来运行查询:

select top 1 ip.*
from t ip
where ip.ipstart > dbo.IPAddressToInteger(@ip)
order by ipstart asc;

运气好的话,这将使用索引并且非常快。然后,您可以比较生成的结束IP,以确保@ip确实在正确的范围内。