【问题标题】:Redesign my database to reduce the query execution time [SQL Server Express]重新设计我的数据库以减少查询执行时间 [SQL Server Express]
【发布时间】:2014-09-06 19:43:50
【问题描述】:

我有下表:

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 编号和掩码。

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

将不胜感激要在数据库中实现的任何其他想法,或者关于如何实现第三种方法的想法。

【问题讨论】:

  • 那么,你的桌子上有什么索引?
  • @OldProgrammer 我可以索引包含非唯一数据的列吗?
  • 是的,您可以索引非唯一数据。
  • @OldProgrammer 非常感谢。您可以将其发布为接受它的答案吗...

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


【解决方案1】:

你想从“网络”的角度来看问题。

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

然后你可以做类似(伪代码)的事情:

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

【讨论】:

    【解决方案2】:

    我在 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
    

    【讨论】:

      猜你喜欢
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多