Ошибка происходит из этой части запроса:
uti_id IN (SELECT DISTINCT ens_utiid_escola, SQRT(POW(69.1 * (uti_latitude - ?), 2) + POW(69.1 * (? - uti_longitude) * COS(uti_latitude / 57.3), 2)) * 1.609344 AS distance
Во-первых, вам не нужно select distinct
в подзапросе in
. Во-вторых, ошибка в том, что у вас есть две строки. Поэтому, если вы хотите использовать эту логику:
uti_id IN (SELECT ens_utiid_escola
FROM . . .
)
Затем вам нужно повторить выражение для distance
, где вы его используете.
Убедитесь, что вы используете индекс, иначе выполняется полное сканирование таблицы. Вы можете посмотреть на план выполнения, чтобы проверить это или вызвать проблему, используя предложение ORDER BY
(для индексированного столбца). Вот дополнительная информация .
Ваша таблица не такая большая, 300 строк. Однако при приближении к таблице возникают проблемы с производительностью. Единственное реальное решение для этого - подделать предложение limit. Имейте поле автоинкремента, которое нумерует строки от 1 до 300 000 и затем делает:
SELECT *
FROM mytable
WHERE field BETWEEN 250000 and 250100
или подобное. Это может быть проблематичным или невозможным, если вы часто удаляете строки, но я склонен обнаруживать, что старые данные имеют тенденцию меняться меньше, поэтому вы можете несколько оптимизировать их, используя LIMIT
для первых 100 000 строк и столбец суррогатной подкачки за этим.
Это действительно весь запрос, или у вас также есть предложение ORDER BY? Потому что это сильно замедлит запросы. Должно помочь, если вы можете получить указатель на полный набор товаров, по которым вы заказываете.
Вы правы: MySQL должен сканировать 250000 бесполезных строк, прежде чем читать те, которые вы хотите. В действительности нет никакого обходного пути для этого сохранения, если разделить таблицу на несколько или иметь хак, например:
SELECT * FROM table WHERE id BETWEEN 250000 AND 250000 + 100 - 1
;or
SELECT * FROM table WHERE id > 250000 ORDER BY id ASC LIMIT 100
Но это все еще не точно подражает функции оператора LIMIT
для сложных запросов. Это скорость: функциональные издержки.
Если у вас есть поле автоинкремента, вы можете просто сделать:
SELECT * FROM table
WHERE ID > @LastID
ORDER BY ID
LIMIT 100