Почему этот запрос на основе диапазона намного быстрее - PullRequest
8 голосов
/ 24 ноября 2010

На работе у нас был запрос к таблице, которая имела следующую структуру:

ip_from(number), ip_to(number), country, city, state, isp, latitude, longitude.

В этой таблице было приблизительно 6,1 миллиона строк.

Чтобы узнать подробности для данного IPВ качестве адреса мы использовали запрос, подобный следующему:

SELECT * 
  FROM Ip2location
WHERE
  :ip_num BETWEEN ip_from AND ip_to;

В Oracle 10 в нашей базе данных разработчиков потребовалось примерно 17 секунд, чтобы вернуть строку, в зависимости от переданного ip_num. В нашей более мощной живой системе этоЭто заняло, может быть, 5–6 секунд, что было слишком медленно в реальном времени, и нам нужно было выбрать это с помощью фоновой работы.

Не идеально, особенно потому, что нашим системам реального времени действительно нужны были данные ip.

Тип используемого индекса - стандартный индекс BTREE, охватывающий ip_from и ip_to.Мы попытались ускорить процесс, например, разбиение диапазона .Мы не применили это в конце концов, поскольку это требует Oracle Enterprise.Мы также смотрели на увеличение параллелизма таблицы, но это не оказало заметного эффекта.

Во всяком случае, когда я пил утренний кофе, я понял, что думаю, что может быть повышение производительности, выполнив следующий запрос: (Это изпамяти, может быть несколько ошибок. Также мы выбрали отдельные поля, а не все)

SELECT * 
  FROM ip2location
WHERE 
  ip_from = (
    SELECT max(ip_from)
      FROM ip2location
      WHERE ip_from <= :ip_num
  )
AND
  ip_to >= ip_num;

Это работает для нашего набора данных, потому что нет перекрывающихся диапазонов между ip_from и ip_to.

Однако я не был готов к тому, насколько быстрее будет второй запрос.Время в нашей базе данных разработчиков было сокращено с 17 до 0,007 секунд.

Для меня это не имеет большого смысла.Я ожидаю некоторого увеличения производительности, но не так сильно.Разве статистика базы данных не должна была определить, что нет перекрытия и оптимизирована соответственно?Кроме того, должен быть признан более быстрый способ выбора с использованием диапазонов?

Мой вопрос: почему второй запрос намного быстрее, даже с использованием дополнительного выбора?

1 Ответ

7 голосов
/ 24 ноября 2010

увеличение производительности очевидно.Это потому, что существует индекс для ip_from, поэтому max (ip_from) можно получить за постоянное время, потому что, как вы знаете, индексация сортирует значения.диапазон также легко вычисляется из-за двоичного поиска по btree.

, в то время как в предыдущем запросе необходимо выполнить сканирование таблицы по всем данным, чтобы вычислить границы диапазона

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