Быстрые SQL-запросы по диапазонам - PullRequest
0 голосов
/ 24 октября 2011

У меня есть таблица IP-диапазонов и их соответствующих городов и стран, которым принадлежит этот IP-диапазон. IP-адреса представлены как bigint (см. Приведенное ниже уравнение для превращения IP-адреса в bigint), и я делаю выбор, чтобы узнать, какие города / страны используют веб-сайт.

Уравнение для преобразования IP в число:

Bigint = (octet1 * (2^24)) + (octet2 * (2^16)) + (octet3 * (2^8)) + Octet 4

Мой выбор выглядит следующим образом. В любом случае, когда у меня есть много IP-адресов (200) для поиска, предложение where может быть очень длинным, а результаты возвращаются в течение нескольких минут. У меня есть startipnum и endipnum, проиндексированные как кластерный индекс. Таблица содержит 6,25 млн строк данных (диапазоны IP-адресов и страны в ней). Есть ли лучший способ вернуть данные?

SELECT [startIpNum] ,[endIpNum],[country],[region],[city],[postal_code]
              ,[latitude],[longitude],[metroCode],[areacode] 
FROM [GeoLocationView] 
WHERE
    (30072067 between startipNum and endipnum) 
    OR
    (30072069 between startipNum and endipnum)

или

SELECT [startIpNum] ,[endIpNum],[country],[region],[city],[postal_code]
              ,[latitude],[longitude],[metroCode],[areacode] 
FROM [GeoLocationView] 
WHERE
     (startipNum <= 30072067 and 30072067 <= endipnum) or 
     (startipNum <= 30072069 and 30072069 <= endipnum)

Ответы [ 3 ]

0 голосов
/ 24 октября 2011

Может быть интересно попробовать использовать переменную таблицы (или временную таблицу) со списком IP-адресов, присоединенных к вашей справочной таблице

declare @ips table (ip bigint)

insert @ips (ip) values (30072067) -- etc...

SELECT <field list>
  FROM [GeoLocationView]
    inner join @ips as ips
      on ((GeoLocationView.startipNum <= ip) and (GeoLocationView.endipnum) >= ip)
0 голосов
/ 24 октября 2011

Когда вам нужно сопоставить множество значений, предложение OR часто медленнее, чем JOIN для временной таблицы.

0 голосов
/ 24 октября 2011

Ваш кластер поможет.

Я бы выбрал x > ? order by x

предложение where может быть вложенным выбором из отдельной таблицы, например так:

where key exists(select * from key_table)

но вы должны сохранить эту key_table ...

Когда он пытается оптимизировать ваш запрос - поиск в таблице лучше обслуживает RDMS, чем хвост ключей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...