MySQL обрабатывает обычные индексы B-дерева, как в большинстве реализаций: Индекс помогает только условие диапазона на крайних левых столбцов в индексе.
Аналогия, которую я использую, - это телефонная книга. Если я ищу конкретную фамилию, имя-пара, как «Смит, Джон», помогает индекс. Мой поиск фамилии «Смит» быстрый, и в «Смитах» поиск «Джона» очень быстрый.
Но если я ищу условия диапазона, такие как «все люди, чья фамилия начинается с« S », тогда я получаю подмножество телефонной книги, но не все люди с именем« Джон »сортируются вместе. Они разбросаны по подмножеству, выбранному мной по фамилии.
Именно по этой причине MySQL выполняет поиск индекса B-дерева до первого условия диапазона, а затем не использует индекс дальше. Вы можете создавать условия для другого измерения, но он будет выполнять ручной поиск по всем строкам, соответствующим первому измерению.
Другими словами, даже если у вас есть составной индекс на (lat, long)
, MySQL не будет использовать long
часть индекса:
select ... from tableName
where lat >= 14.1232 and lat <=13.123 /* index-assisted */
and lng >=-80.123 and lng <=-79.232 /* full scan */
and name like '%greg%' /* pattern search never uses index anyway */
(Кстати, ваш лат состояние никогда не может быть правдой, как вы написали, но я предполагаю, что вы имеете в виду номера, которые нужно обратить вспять.)
Это делает неэффективным выполнение широты & долготы, так как оба выполняют поиск по целому ряду значений.
По этой причине у MySQL есть другой тип индекса, который не является индексом B-дерева. Это индекс SPATIAL
, который поддерживает несколько условий диапазона.
CREATE TABLE mytable (
name TEXT NOT NULL,
coord POINT NOT NULL,
SPATIAL INDEX (coord)
);
INSERT INTO mytable (name, coord)
VALUES ('name', ST_GeomFromText('POINT(14.0 -80)'));
SELECT name FROM mytable
WHERE MBRContains(
ST_GeomFromText('Polygon((
13.123 -80.123,
14.1232 -80.123,
14.1232 -79.232,
13.123 -79.232,
13.123 -80.123))'),
coord);
Да, это сложнее, но это единственный способ, которым Вы можете получить поистине индексный оптимизированный поиск широты/долготы.
Подробнее об этом здесь: http://dev.mysql.com/doc/refman/5.7/en/using-spatial-data.html
Похоже, вы уже это сработало. Вы добавили индекс в столбцы lat и lng, или это то, что вы спрашиваете, как это сделать? – mba12
им просто интересно, как mysql обрабатывает порядок его запроса ... Я уверен, что первая часть запроса (индексированная лат) сужает его, но как насчет второй части запроса? (indexed lng) – rikkitikkitumbo