我有大约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
答案 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
确实在正确的范围内。