Return记录起始IP和结束IP作为IP地址范围?
Return record with start IP and end IP as range that an IP address falls between?
我有大约 550 万条包含 IP 地址信息的记录。 table 每条记录都有一个低端和一个高端。我们将此范围称为 ip_start
和 ip_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
确实在正确的范围内。
我有大约 550 万条包含 IP 地址信息的记录。 table 每条记录都有一个低端和一个高端。我们将此范围称为 ip_start
和 ip_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
确实在正确的范围内。