sql 行政区划关联查询优化_最新IP数据库 存储优化 查询性能优化 每秒解析上千万...

高性能IP数据库格式详解

每秒解析1000多万ip  qqzeng-ip-ultimate.dat 3.0版编码:UTF8字节序:Little-Endian

返回规范字段(如:亚洲|中国|香港|九龙|油尖旺|新世界电讯|810200|Hong Kong|HK|114.17495|22.327115)

------------------------ 文件结构  -------------------------

// 文件头 4字节

[IP段数量]

// 前缀区 8字节(4-4) 256*8

[索引区start第几个][索引区end第几个]

// 索引区 8字节(4-3-1) ip段行数x8

[结束IP数字][地区流位置][流长度]

// 内容区 长度无限制

[地区信息][地区信息]……唯一不重复

------------------------ 文件结构 ---------------------------

优势:压缩形式将数据存储在内存中,通过减少将相同数据读取到内存的次数来减少I/O.

较高的压缩率通过使用更小的内存中空间提高查询性能。

前缀区为作为缩小查询范围,索引区和内容区长度一样,

解析出来一次性加载到数组中,查询性能提高3-5倍!

压缩:原版txt为38.5M,生成dat结构为3.68M 。

和上一版本2.0不同的是索引区去掉了[开始IP数字]4字节,节省多1-2M。

3.0版本只适用[全球版],条件为ip段区间连续且覆盖所有IPV4。

2.0版本适用[全球版][国内版][国外版]

性能:每秒解析1000多万ip

创建:qqzeng-ip 于 2018-04-08

性能测试( CPU i7-7700K + DDR2400 16G + win10 X64 )

查询【3.0】内存优化版 3414万ip->3.318秒 每秒1028.93309222423万次

查询【3.0】内存优化版 4439万ip->4.199秒 每秒1057.1564658252万次

查询【3.0】内存优化版 4056万ip->3.821秒 每秒1061.50222454855万次

查询【3.0】内存优化版 1781万ip->1.68秒 每秒1060.11904761905万次

查询【3.0】内存优化版 3862万ip->3.66秒 每秒1055.1912568306万次

查询【3.0】内存优化版 3479万ip->3.31秒 每秒1051.05740181269万次

查询【3.0】内存优化版 2892万ip->2.713秒 每秒1065.97862145227万次

查询【3.0】内存优化版 3484万ip->3.263秒 每秒1067.72908366534万次

查询【3.0】内存优化版 2699万ip->2.548秒 每秒1059.26216640502万次

查询【3.0】内存优化版 88万ip->0.087秒 每秒1011.49425287356万次

查询【3.0】内存优化版 161万ip->0.153秒 每秒1052.28758169935万次

查询【3.0】内存优化版 91万ip->0.088秒 每秒1034.09090909091万次

查询【3.0】内存优化版 42万ip->0.041秒 每秒1024.39024390244万次

查询【3.0】内存优化版 159万ip->0.152秒 每秒1046.05263157895万次

查询【3.0】内存优化版 88万ip->0.084秒 每秒1047.61904761905万次

查询【3.0】内存优化版 123万ip->0.118秒 每秒1042.37288135593万次

查询【3.0】内存优化版 106万ip->0.101秒 每秒1049.50495049505万次

查询【3.0】内存优化版 61万ip->0.059秒 每秒1033.89830508475万次

查询【3.0】内存优化版 177万ip->0.169秒 每秒1047.33727810651万次

查询【3.0】内存优化版 106万ip->0.101秒 每秒1049.50495049505万次

查询【3.0】普通优化版 1464万ip->3.408秒 每秒429.577464788732万次

查询【3.0】普通优化版 352万ip->0.803秒 每秒438.356164383562万次

查询【3.0】普通优化版 1357万ip->3.042秒 每秒446.088099934254万次

查询【3.0】普通优化版 184万ip->0.43秒 每秒427.906976744186万次

查询【3.0】普通优化版 752万ip->1.697秒 每秒443.134944018857万次

查询【3.0】普通优化版 1795万ip->4.032秒 每秒445.188492063492万次

查询【3.0】普通优化版 1823万ip->4.076秒 每秒447.252208047105万次

查询【3.0】普通优化版 723万ip->1.622秒 每秒445.745992601726万次

查询【3.0】普通优化版 136万ip->0.319秒 每秒426.332288401254万次

查询【3.0】普通优化版 334万ip->0.756秒 每秒441.798941798942万次

查询【3.0】普通优化版 636万ip->1.435秒 每秒443.205574912892万次

查询【3.0】普通优化版 701万ip->1.578秒 每秒444.233206590621万次

查询【3.0】普通优化版 1807万ip->4.07秒 每秒443.980343980344万次

查询【3.0】普通优化版 489万ip->1.105秒 每秒442.533936651584万次

随机生成 IP

RNGCryptoServiceProvider rngCsp = newRNGCryptoServiceProvider();byte[] bytes = new byte[4];

rngCsp.GetBytes(bytes);uint value = ReadBigEndian32(bytes[0], bytes[1], bytes[2], bytes[3]);

开发参考(解析dat以及查询)

public classIPSearch3Fast

{private static readonly Lazy lazy = new Lazy(() => newIPSearch3Fast());public static IPSearch3Fast Instance { get { returnlazy.Value; } }privateIPSearch3Fast()

{

LoadDat();

Watch();

}private string datPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"qqzeng-ip-ultimate.dat");private DateTime lastRead =DateTime.MinValue;private long[,] prefmap = new long[256, 2];private uint[] endArr;private string[] addrArr;private byte[] data;///

///初始化二进制 qqzeng-ip-ultimate.dat 数据///

private voidLoadDat()

{

data=File.ReadAllBytes(datPath);for (int k = 0; k < 256; k++)

{int i = k * 8 + 4;int prefix =k;long startIndex = ReadLittleEndian32(data[i], data[i + 1], data[i + 2], data[i + 3]);long endIndex = ReadLittleEndian32(data[i + 4], data[i + 5], data[i + 6], data[i + 7]);

prefmap[k,0] = startIndex; prefmap[k, 1] =endIndex;

}uint RecordSize = ReadLittleEndian32(data[0], data[1], data[2], data[3]);

endArr= new uint[RecordSize];

addrArr= new string[RecordSize];for (int i = 0; i < RecordSize; i++)

{long p = 2052 + (i * 8);uint endipnum = ReadLittleEndian32(data[p], data[1 + p], data[2 + p], data[3 +p]);int offset = data[4 + p] + ((data[5 + p]) << 8) + ((data[6 + p]) << 16);int length = data[7 +p];

endArr[i]=endipnum;

addrArr[i]=Encoding.UTF8.GetString(data, offset, length);

}

}private voidWatch()

{

FileInfo fi= newFileInfo(datPath);

FileSystemWatcher watcher= newFileSystemWatcher(fi.DirectoryName)

{

IncludeSubdirectories= false,

NotifyFilter=NotifyFilters.LastWrite,

Filter= "qqzeng-ip-ultimate.dat",

};

watcher.Changed+= (s, e) =>{var lastWriteTime =File.GetLastWriteTime(datPath);if (lastWriteTime >lastRead)

{//延时 解决 正由另一进程使用,因此该进程无法访问此文件

Thread.Sleep(1000);

LoadDat();

lastRead=lastWriteTime;

}

};

watcher.EnableRaisingEvents= true;

}///

///ip快速查询方法///

/// 1.1.1.1

///

public string Find(stringip)

{long val = IpToInt(ip, out longpref);long low = prefmap[pref, 0], high = prefmap[pref, 1];long cur = low == high ?low : BinarySearch(low, high, val);returnaddrArr[cur];

}//二分逼近 O(logN)

private long BinarySearch(long low, long high, longk)

{long M = 0, mid = 0;while (low <=high)

{

mid= (low + high) / 2;uint endipnum =endArr[mid];if (endipnum >=k)

{

M=mid;if (mid == 0)

{break; //防止溢出

}

high= mid - 1;

}elselow= mid + 1;

}returnM;

}

private long IpToInt(string ipString, out longprefix)

{//高性能

int end =ipString.Length;unsafe{fixed (char* name =ipString)

{int numberBase = 10;charch;long[] parts = new long[4];long currentValue = 0;int dotCount = 0;int current = 0;for (; current < end; current++)

{

ch=name[current];

currentValue= 0;

numberBase= 10;if (ch == '0')

{

numberBase= 8;

current++;if (current

{

ch=name[current];if (ch == 'x' || ch == 'X')

{

numberBase= 16;

current++;

}

}

}for (; current < end; current++)

{

ch=name[current];intdigitValue;if ((numberBase == 10 || numberBase == 16) && '0' <= ch && ch <= '9')

{

digitValue= ch - '0';

}else if (numberBase == 8 && '0' <= ch && ch <= '7')

{

digitValue= ch - '0';

}else if (numberBase == 16 && 'a' <= ch && ch <= 'f')

{

digitValue= ch + 10 - 'a';

}else if (numberBase == 16 && 'A' <= ch && ch <= 'F')

{

digitValue= ch + 10 - 'A';

}else{break;

}

currentValue= (currentValue * numberBase) +digitValue;

}if (current < end && name[current] == '.')

{

parts[dotCount]=currentValue;

dotCount++;continue;

}break;

}

parts[dotCount]=currentValue;

prefix= parts[0];return (parts[0] << 24) | ((parts[1] & 0xff) << 16) | ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);

}

}//简洁的 普通//byte[] b = IPAddress.Parse(ip).GetAddressBytes();//prefix = b[0];//return ReadBigEndian32(b[0], b[1], b[2], b[3]);

}private uint ReadBigEndian32(byte a, byte b, byte c, byted)

{return (uint)((a << 24) | (b << 16) | (c << 8) |d);

}private uint ReadLittleEndian32(byte a, byte b, byte c, byted)

{return (uint)(a | (b << 8) | (c << 16) | (d << 24));

}

}/*(调用例子):

string result = IPSearch3Fast.Instance.Find("1.2.3.4");

--> result="亚洲|中国|香港|九龙|油尖旺|新世界电讯|810200|Hong Kong|HK|114.17495|22.327115"*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值