重新设计我的数据库以减少查询执行时间[SQL Server Express]

时间:2014-09-06 19:43:51

标签: sql sql-server database performance sql-execution-plan

我有下表:

Network_id: varchar(15) (it's an IP-Address)
mask:       tinyint     (values: 1-32)
AS:         bigint      (values: 0-400000)

此表有大约800,000行。

我有一个IP地址作为输入,我试图找出它属于哪个网络。

我尝试了很多方法。

方法一:

我将表的结构转换为:

start_ip, end_ip

并编写了一个存储过程来查明ip地址是否介于2个ip地址之间,然后写了另一个存储过程,该过程使用CURSOR迭代表的记录并调用第一个过程并在获取命中时打破并返回所选记录。

此方法需要大约15-20秒才能达到要求,有时我会在得到结果之前收到超时错误。

所以,我尝试了方法二:

方法二

我尝试将ip地址分成tinyint类型的x.y.z.t,并尝试选择x,y,z,t条件具有特定值的记录。

同一时间和相同的结果

方法三:

我对这种方法有所了解,但我没有实现它。

我们可以创建一个5级的树

  • IP地址:x.y.z.t
  • 等级0到等级1:保持边缘的x值。
  • 等级1到等级2:保持边缘的y值。
  • 等级2到等级3:保持边缘的z值。
  • 等级3到等级4:保持边缘的t值。
  • 5级叶子在每个叶子内部保留AS编号和掩码。

我认为这种方式对我有很大帮助,但我没有找到在数据库设计中实现它的方法。

将赞赏在数据库中实现的任何其他想法,或者如何实现第三种方法的想法。

2 个答案:

答案 0 :(得分:0)

您希望从“网络”的角度来看问题。

使用“基本”网络地址(IPv4为32位)和“掩码”来定义您的表,让您知道范围。

然后你可以做一些像(伪代码):

   select networkName
     from networkDefinition n
    where (n.ip = n.mask <bitwise and> <search address>
    order by n.mask descending

答案 1 :(得分:0)

我在sql server中设计了一个ip-geolocation数据库,并且能够通过ip地址聚集的单个表获得出色的性能,例如:

create table ip2location (
   ip_start binary(4) not null,
   location_id int not null,
   primary key clustered (ip_start))

而不是拥有ip_start和ip_end列,我只是假设范围是连续的并且具有“未知”的location_id

查找给定IP地址的位置很快就像这样查询:

select top 1 location_id from ip2location
where ip_start <= @some_ip order by ip_start desc