Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Querying Sql server with index for range

I am using SQL SERVER 2012 that is running on windows datacenter 2012,

I have a database with a table that is build as followed :

[ID] (pk,int not null)
[Start] (float,null)
[End] (float, null)
[CID] (int,null) --country id

I have a web service that gets an IP, translate it to decimal (may refer to this : IP address conversion to decimal and vice versa) and request the database server for the country id

The table mentioned at first contains ~200K rows with start and end values representing IP ranges as decimal and a countryid related to each range,

I have encountered a really high CPU usage against some heavy traffic we have been dealing, so i added indexes on the start and end columns, afterwards the cpu got a little bit better but i think it should have been much more, its simply suppose to work as a search in a sorted list which should be extremely fast, though the expected result i had from adding the index were far from reality,

I suppose it is because its not searching a list but searching a range

What would be the best way to efficient this situation, since i am just sure that the resources this simple action is taking me is way to much than it should.

Here is a picture from the activity monitor now (lower traffic, after indexing) : enter image description here

This is running on Azure ExtraLarge VM (8 cores 14GB memory) - the vm is doing nothing but running a sql server with 1 table that only translates this 1 request ! the VM CPU on this lower traffic is ~30% and ~70% on higher traffic, i am sure some structure/logical changes should make a really small server\service handle this easily.

like image 791
Matan L Avatar asked Oct 21 '22 23:10

Matan L


1 Answers

SELECT TOP 1 *
FROM IP
WHERE StartIP <= yourIP
ORDER BY StartIP

This gets you the nearest IP range above the given IP. You then need to test whether the EndIP also matches. So:

SELECT *
FROM (
 SELECT TOP 1 *
 FROM IP
 WHERE StartIP <= yourIP
 ORDER BY StartIP
) x
WHERE EndIP >= yourIP

This amounts to a single-row index seek. Perfect performance.

The reason SQL Server cannot automatically do this is that it cannot know that IP ranges are ordered, meaning that the next StartIP is always greater than the current EndIP. We could have ranges of the form (100, 200), (150, 250). That is clearly invalid but it could be in the table.

like image 194
usr Avatar answered Oct 23 '22 16:10

usr