Sql-Server
在兩個 bigint 列之間搜尋的查詢的最佳索引策略
我在 MS-SQL 中有下表:
CREATE TABLE [dbo].[dbip_locations]( [ip_from] [bigint] NOT NULL, [ip_to] [bigint] NOT NULL, [country_code] [nvarchar](64) NOT NULL, [region_name] [nvarchar](128) NOT NULL, [city_name] [nvarchar](128) NOT NULL, [latitude] [float] NOT NULL, [longitude] [float] NOT NULL )
ip_from 和 ip_to 列是根據 ipv4 地址計算的,如下所示:
return ( convert(bigint, parsename(@ip, 1)) + convert(bigint, parsename(@ip, 2)) * convert(bigint, 256) + convert(bigint, parsename(@ip, 3)) * convert(bigint, 65536) + convert(bigint, parsename(@ip, 4)) * convert(bigint, 16777216) )
然後,我使用通過上述計算轉換為 bigint 的 ipv4 地址來搜尋 ip 地址位於 ip_from 和 ip_to 列之間的行。
我總是會找到一行,雖然它不是由模式強制執行的,但這是數據中的現實。
這是查詢:
SELECT TOP(1) [latitude], [longitude] FROM [dbo].[dbip_locations] WHERE @ip_int BETWEEN ip_from AND ip_to
我目前在 ip_from 和 ip_to 列上有兩個非聚集、非唯一索引。查詢執行得非常快,但我每秒執行大量此類查詢,我想知道是否可以通過使用不同的索引來獲得更好的性能?也許是聚集的多列索引或使用唯一索引?
我可以使用更好的索引嗎?
我認為具有 ip_from 和 ip_to 的複合索引對於此範圍搜尋將是最有效的。如果返回的唯一列是緯度和經度,則這些查詢應作為非鍵列包含在非集群中,以獲得此特定查詢的最佳性能。索引應該是聚集的,而不是你經常返回其他列。
因為您的查詢
TOP (1)
沒有指定ORDER BY
,所以在範圍搜尋中可能會返回任何任意行。如果您每次都需要返回相同的行,請使用列指定“ORDER BY”以唯一標識行。