Здравствуйте, форумчане! Нужен совет, поделитесь опытом. Есть две таблицы с географическими координатами точек. Допустим так: table1 (Long decimal(12,8),Lat decimal(12,8),present int) и table2(Long decimal(12,8),Lat decimal(12,8)) В обеих таблицах созданы составные индексы по полям Long и Lat Задача написать запрос, который апдейтит поле present в table1 если такие координаты есть в table2. Но проблема заключается в том, что требуется не точное совпадение, а +/- delta. Delta = 0.002 Пишу так: Код (Text): update table1 t1 join table2 t2 on t1.Long between t2.aLong-0.002 and t2.aLong+0.002 and t1.Lat between t2.aLat-0.002 and t2.aLat+0.002 set t1.present = 1 Но эта вещь оказывается убийственной для сервера. На мощном сервере она всё-таки завершилась, но работала более 2 часов, на моем домашнем (слабеньком) 6 часов и нет результатов. В таблице table1 36000 записей, в table2 188000 записей.
Присоединяюсь. Запрос должен выполняться меньше секунды. --- Добавлено --- Пожалуй я погорячился. Поправка: Запрос должен выполняться несколько секунд.
Естественно долго будет, т.к. идёт пересечение таблиц (т.е. будет отработано около 6 млрд. чтений из таблиц, это долго) Попробуй заменить выражение на эквивалент, чтобы использовался индекс: PHP: update table1 t1 -- join table2 t2 on (t1.Long between t2.aLong-0.002 and t2.aLong+0.002) and (t1.Lat between t2.aLat-0.002 and t2.aLat+0.002) join table2 t2 on (t1.Long+0.002 >= t2.aLong and t1.Long-0.002 <= t2.aLong) and (t1.Lat+0.002 >= t2.aLat and t1.Lat-0.002 <= t2.aLat) set t1.present = 1 У меня отрабатывает ~1.1 секунды (mySQL-5.6, Innodb, Win-7). Только надо проверить результат. Теоретически всё правильно, но вдруг я ошибаюсь...
Много, - через 5 минут остановил выполнение. Судя по скорости работы движка будет отрабатывать где-то от часа до двух.
@Chushkin Спасибо! Если это работает с индексами - я неимоверно благодарен . Правда explain мне показал, что этот запрос тоже индексы не использует, но это ещё проверить надо. Сейчас перезагружу таблицы, хочу удалить от туда южное полушарие и западное. Короче четверть земли оставлю, остальное пока не интересно.
Explain показывает "Range checked for each record (index map: 0x2)". Т.е. индекс используется, если верить доке. Да и результат говорит за это.
Спасибо огромное, у меня дома на слабой железяке (ARM Linux 512 Mb RAM) всё отработало за несколько секунд! Добавлю, всё отработало корректно.