I have a table that contains ranges of IP addresses (as integer values) and corresponding country, region and city assigned to that range. It looks as follows:
CREATE TABLE [dbo].[IpToRegion]
(
[BeginRange] [bigint] NOT NULL,
[EndRange] [bigint] NOT NULL,
[CountryCode] [varchar](10) NOT NULL,
[Country] [varchar](50) NOT NULL,
[Region] [varchar](100) NOT NULL,
[City] [varchar](100) NOT NULL
) ON [PRIMARY]
CREATE UNIQUE CLUSTERED INDEX [ClusteredIndex-20151031-193911] ON [dbo].[IpToRegion]
(
[BeginRange] ASC,
[EndRange] ASC
)
GO
There are 9.1M rows in this table. In order to find the location of a single IP address, I first convert it to a big int and then execute the following query:
DECLARE @IPNumber BIGINT
DECLARE @IPAddress varchar(20)
Set @IPNumber = (CONVERT(bigint, PARSENAME(@IPAddress,1)) + CONVERT(bigint, PARSENAME(@IPAddress,2)) * 256 + CONVERT(bigint, PARSENAME(@IPAddress,3)) * 65536 + CONVERT(bigint, PARSENAME(@IPAddress,4)) * 16777216)
Select City + ', ' + Region + ', ' + Country
From IpToRegion
Where @IPNumber Between BeginRange And EndRange
The problem is this query can take anywhere from 5 to 20 seconds to execute. Here is the query plan:
Of course, my question is how can this query take so long to execute? It's doing a seek on the clustered index and returns a single row. I could try a few different indexing strategies. But, at this point, I'm more curious as to why this query can perform so poorly.