2014-09-06 49 views
0

我有如下表:重新設計我的數據庫,以減少查詢執行時間[SQL Server Express的]

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地址XYZT tinyint類型的分裂成碎片並試圖選擇與x的其中條件,Y的記錄, z,t具有特定的值。

相同的時間和相同的結果

方法三:

我有這個方法的想法,但我並沒有實現它。

我們可以創建5個等級

  • IP地址的樹:x.y.z.t
  • 0級到1級:持有邊緣上的x值。
  • 等級1到等級2:保持邊緣上的y值。
  • 等級2到等級3:保持邊緣上的z值。
  • 3級到4級:保持邊緣上的t值。
  • 5級葉子每個人都擁有AS號碼和掩碼。

我認爲這種方式會幫助我很多,但我沒有找到一種方法在數據庫設計中實現它。

任何其他想在數據庫中實現的想法將不勝感激,或者關於如何實現第三種方法的想法。

+0

那麼,你有什麼指標在桌子上? – OldProgrammer 2014-09-06 19:59:56

+0

@OldProgrammer我可以使用非唯一數據索引一列嗎? – user3098586 2014-09-06 20:02:36

+0

是的,你可以索引非唯一的數據。 – OldProgrammer 2014-09-06 20:06:42

回答

0

你想從「網絡」的角度來看問題。

通過使用「基本」網絡地址(32位IPv4)和可以讓您知道範圍的「掩碼」來定義您的表。

然後,你可以這樣做(僞):

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

我設計在SQL Server的IP地理位置數據庫,並能與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