SQL запрос выполняется слишком долго как его можно оптимизировать Код (Text): SELECT concat(country.name, ', ', region.name, ', ', city.name, ', ', raion.name) AS temp FROM mlt_adr_country country LEFT JOIN mlt_adr_city city ON country.id = city.country_id LEFT JOIN mlt_adr_region region ON city.region_id = region.id LEFT JOIN mlt_adr_raion raion ON city.raion_id = raion.id WHERE CASE WHEN (SELECT * FROM (SELECT count(name) FROM mlt_adr_country WHERE name LIKE 'Россия%') as tem) > 0 THEN country.name LIKE 'Россия%' WHEN (SELECT * FROM (SELECT count(name) FROM mlt_adr_city WHERE name LIKE 'Теплу%') as tem) > 0 THEN city.name LIKE 'Теплу%' END GROUP BY city.id Сейчас он выполняется 30 сек всего 200к записей Условий будет таких же ещё штук пять Т.е. примерно запрос будет около минуты выполняться. Как возможно его переделать
Вот от этого надо избавиться WHEN (SELECT * FROM (SELECT count(name) FROM mlt_adr_country WHERE name LIKE 'Россия%') as tem) > 0 THEN WHEN (SELECT * FROM (SELECT count(name) FROM mlt_adr_city WHERE name LIKE 'Теплу%') as tem) > 0 THEN Добавлено спустя 1 минуту 1 секунду: т.к. эти запросы у вас постоянные, то сделайте их перед большим запросом и подставляйте результат.
Вообще в целом идея такая, что бы сделать поиск с автозаполнением как на google maps. Именно по регионам городам странам. Что бы например в одно и то же поле можно было написать москва или московская область или например москва ленинградское шоссе ну и соответственно он максимально близко понимал текст который впишет пользователь и вывел наиболее подходящие записи.
Да ) прочел, я подумал на счет этого следующим образом, почему бы это не разделить. Отдельно выполнить запрос, И если он нам вернет хоть одну строку, то тогда подставляем определенный параметр в более тяжелый запрос. Но тогда маленьких запросов может быть гораздо больше. И при одном поисковом запросе выполнять пять лишних....... Добавлено спустя 3 минуты 21 секунду: Кстати ещё если просто выполнить Код (Text): SELECT concat(country.name, ', ', region.name, ', ', city.name, ', ', raion.name) AS temp FROM mlt_adr_country country LEFT JOIN mlt_adr_city city ON country.id = city.country_id LEFT JOIN mlt_adr_region region ON city.region_id = region.id LEFT JOIN mlt_adr_raion raion ON city.raion_id = raion.id WHERE country.name LIKE 'Р%' GROUP BY city.id И этот запрос выполняется 30 секунд И почему то если сделать LIMIT 5, то выполняется столько же, ну чуть чуть меньше на несколько мили секунд.
надо выбрать те, кого вам надо, потом заюзать конструкцию типа WHERE `id` IN (1,2,3,4,...) если надо ещё что-то, то добавлять поля с предварительно просчитанными данными. Например " concat(country.name, ', ', region.name, ', ', city.name, ', ', raion.name) AS temp " хорошо бы вкрячить в виде поля в какую-нить таблицу. Это будет некоторым кешем, позволяющим индексацию, и соотв ускорение всего этого дела.
Мы не как не выберем поле то одно. И соответственно нужно исходить из одного поля Вот пример на google maps там же поле одно, не ужели оно все из одной таблицы берет... Добавлено спустя 5 минут 9 секунд: Убрал GROUP BY и добавил LIMIT 5 запрос выполняется 0,100 сек, Но почему используя GROUP BY он так тормозит да же если добавить LIMIT 5 процесс не сильно то изменяется
если учесть все правила "не и ни" и запятые, то я всё равно не понял смысл фразы. Добавлено спустя 1 минуту 41 секунду: потому что сначала делается выборка, потом уже групбай, а потом сортировка, потом лимит =) попробуй LIMIT 100000, 5. Сначала построится 100005 таблица, потом всё остальное
Возможно я не правильно понял смысл нижней фразы И вот как я выберу тех кого мне надо? Если например кто то захочет написать "РОССИЯ", а кто то "КИРОВ ул МИРА" И в качестве автозаполнения должно будет предложено максимально похожий вариант
WHEN (SELECT * FROM (SELECT count(name) FROM mlt_adr_country WHERE name LIKE 'Россия%') as tem) > 0 THEN WHEN (SELECT * FROM (SELECT count(name) FROM mlt_adr_city WHERE name LIKE 'Теплу%') as tem) > 0 THEN сделай эти выборки ПЕРЕД большим запросом, а в него вставь уже результат. Иначе ты делаешь эти выборки на каждую строку каждый раз *каждый раз * на второй позапрос каждый раз * каждый раз...
Самый быстрый вариант - для автозаполнения создай вообще отдельную таблицу. Одну. В ней (в одной колонке) перечисли все тексты, которые имеются в базе, по которым может быть поиск. А лучше даже пихай туда не все, а только наиболее вероятные к поиску. Мелкие деревеньки сибири - можешь туда не писать, только города. Добавлено спустя 1 минуту 32 секунды: При добавлении/редактировании записей в таблицах country/region/raion/city - автоматически также добавляй/редактируй записи в этой дополнительной таблице. Добавлено спустя 6 минут 22 секунды: Тогда поиск будет простым Код (Text): SELECT * FROM `autocomplete_table` WHERE `text_field` LIKE '%search_text%';
И медленным, ибо никаких индексов. Более правильным, по моему мнению, будет простая табличка, где хранятся варианты запросов юзера, и полнотекстовый поиск (с индексированием, естественно) - будет работать быстро, даже без кеширования (сотые доли секунды).
У меня на счет этого то же есть мысли, только вот правда не знаю в плане скорости как это дело будет. Вот тут я не совсем понимаю, можно по подробнее, как я соберу варианты запросов Юзера?