Return记录起始IP和结束IP作为IP地址范围?

Return record with start IP and end IP as range that an IP address falls between?

我有大约 550 万条包含 IP 地址信息的记录。 table 每条记录都有一个低端和一个高端。我们将此范围称为 ip_startip_end。这是混合的 IPv4 和 IPv6 地址。

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

即使只考虑 IPv4 地址,运行转换找到的函数 here 需要整整 58 秒才能 运行结束范围。很明显,这是 unacceptable.

我可以在 C# 中执行此操作,但老实说我认为 SQL 会更快,因为我正在使用 entity framework 并且我将通过 WCF 进行网络调用...越少我扔过电线的次数越多越好。

我考虑过 运行使用先前提供的 link 中的函数进行转换,并有两个索引 bigint 列,但是......我到底该怎么办有 IPv6 地址?显然我不能以相同的方式转换它们,因为 IPv6 地址中的空部分实际上是空的,而 IPv4 中有一个奇怪的 "similar" 0。

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

并且仅供参考,link 提及为我们提供了以下功能:

create function dbo.IPAddressToInteger(@ip as varchar(15))
   returns bigint
as
begin
return (
  convert(bigint, parsename(@ip, 1)) +
  convert(bigint, parsename(@ip, 2)) * 256 +
  convert(bigint, parsename(@ip, 3)) * 65536 +
  convert(bigint, parsename(@ip, 4)) * 16777216
)
end
go

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

首先,更新您的 table 以获得整数 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 确实在正确的范围内。