Sql-Server

在兩個 bigint 列之間搜尋的查詢的最佳索引策略

  • December 22, 2016

我在 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”以唯一標識行。

引用自:https://dba.stackexchange.com/questions/157334