Есть ли способ оптимизировать MySQL Query, который выполняет функцию на каждой строке? - PullRequest
0 голосов
/ 22 июня 2010

У меня есть запрос MySQL, который извлекает значения lat long из базы данных на основе критерия, проверяет, находятся ли эти точки внутри многоугольника, и возвращает точки, которые находятся внутри многоугольника.

Все работает нормально,Проблема в том, что запрос занимает ок.20 секунд, чтобы вернуть результат.Есть ли способ оптимизировать этот запрос так, чтобы скорость запроса была выше?

SELECT latitude, longitude
FROM myTable
WHERE offense = 'green' AND myWithin(
POINTFROMTEXT( CONCAT( 'POINT(', latitude, ' ', longitude, ')' ) ) , POLYFROMTEXT( 'POLYGON(( ...bunch of lat longs...))' )
) = 1;

Я запустил EXPLAIN SELECT ..., который произвел

id |select_type |стол |тип |возможные_ключи |ключ |key_len |ref |строки |Extra

1 SIMPLE myTable ALL NULL NULL NULL NULL 137003 Использование где

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

Я думаю о том, чтобы сделать выборку в другую таблицу и затем запросить таблицу результатов, но я надеялся, что будет способ улучшить производительность этого запроса.

Если у кого-нибудь есть какие-либо предложения или идеи, я бы с удовольствием их выслушал.

Спасибо,

Лакшмиди

Ответы [ 2 ]

1 голос
/ 22 июня 2010

Насколько велики полигоны? Вы можете определить «ограничивающий прямоугольник» вокруг всего многоугольника и затем сделать:

SELECT latitude, longitude
FROM myTable
WHERE
  offense = 'green' AND
  latitude BETWEEN rect_left AND rect_right AND
  longitude BETWEEN rect_top AND rect_bottom AND
  myWithin(
    POINTFROMTEXT( CONCAT( 'POINT(', latitude, ' ', longitude, ')' ) ),
    POLYFROMTEXT( 'POLYGON(( ...bunch of lat longs...))' )) = 1;

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

0 голосов
/ 22 июня 2010

Я вижу два очевидных пути для оптимизации:

  • Уменьшите набор результатов еще до того, как вы запустите свою функцию O (n) раз.Прямо сейчас вы запускаете функцию 137003 раза - мало что можно избежать, если вы не сможете отфильтровать результирующий набор дальше.

  • Сделайте функцию быстрее, так что вы 'мы по-прежнему выполняем его 137k раз, но каждый вызов занимает меньше времени, что сокращает общее время выполнения.

В данный момент ваша функция запускает 0,1459 миллисекунд на строку, что на самом деле не такплохой.Возможно, вы захотите попытаться найти способ еще больше уменьшить количество строк, на которых вы должны его запустить.Сокращение результирующего набора за счет грамотного использования WHERE также имеет побочное преимущество, заключающееся в том, что ваша база данных может выполнить некоторую оптимизацию за вас - именно так, как вы хотите ее использовать.

...