powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / SQL запрос выполняется 90 секунд
22 сообщений из 22, страница 1 из 1
SQL запрос выполняется 90 секунд
    #39505073
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет ребят. Такая проблема. Есть запрос, который агрегирует данные из 10 таблиц, в итоге он выполняется 95 секунд. Вот сам запрос:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT company.id, company.name as name, company.city as city, company.user_id, company.site as site, company.address as address,
  IFNULL(GROUP_CONCAT(distinct(activity.name) SEPARATOR ', '),'не указано') as activity,
  IFNULL(GROUP_CONCAT(DISTINCT(mark.name) SEPARATOR ', '),'не указано') as marks,
  IFNULL(GROUP_CONCAT(DISTINCT(production.name) SEPARATOR ', '),'не указано') as production,
  IFNULL(GROUP_CONCAT(distinct(country.name) SEPARATOR ', '),'не указано') as country, result.name as result, result.id as resultId, company.comment,
  IF(CHAR_LENGTH(TRIM(IFNULL(company.stock, "")))>0,TRIM(IFNULL(company.stock, "Не указано")),"Не указано") as stock, company.interest, company.email,
  company.dispatch
FROM company
  LEFT JOIN activity_link as al on company.id = al.company_id AND al.deleted = 0
  LEFT JOIN activity on activity.id = al.activity_id
  LEFT JOIN production_link as pl on company.id = pl.company_id AND pl.deleted = 0
  LEFT JOIN production on production.id = pl.production_id
  LEFT JOIN country_link as cl on company.id = cl.company_id AND cl.deleted = 0
  LEFT JOIN country on country.id = cl.country_id
  LEFT JOIN result on company.result_id = result.id
  LEFT JOIN mark_link as ml on company.id = ml.company_id AND ml.deleted = 0
  LEFT JOIN mark on mark.id = ml.mark_id
WHERE company.deleted = 0
GROUP BY company.id
ORDER BY company.id DESC LIMIT 0, 30


Можно ли его как-то оптимизировать? Я уже все перепробовал, ставил индексы, пробовал переписывать его, но все тщетно. Мне пришлось временно удалить JOIN с таблицей mark_link, в итоге запрос стал выполняться примерно за 250 мс. Помогите пожалуйста, уже не знаю что делать =(
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505101
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrApson,

вы забыли explain показать.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505109
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MelkijMrApson,

вы забыли explain показать.
С EXPLAIN
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505229
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrApson,

скорее всего барахлит анализатор

1. сделайте OPTIMIZE таблиц

2. какая скорость если оставить только ML ?

3. перепишите таблицу чтоб первые 6-7 джоинтов были в отдельном сабселекте а потом
джоин на ML

4. сделайте ЛИМИТ 0,30 в самом начале ОТДЕЛЬНО от всего остального
а потом навешивайте все остальное

(Експлейн похоже нормальный, но движок где-то тормозит.
варианты (3) и (4) -- фактически некая подсказак движку сделать
правильно не только на екплейне но и в реальном прогоне )

()
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505233
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сейчас уеду на час-полтора, приеду и распишу.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505358
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы каждую группу (company + data_link + data) убрал в отдельный подзапрос, чем избавился от DISTINCT.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505422
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrApsonПривет ребят. Такая проблема. Есть запрос, который агрегирует данные из 10 таблиц, в итоге он выполняется 95 секунд. Вот сам запрос:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT company.id, company.name as name, company.city as city, company.user_id, company.site as site, company.address as address,
  IFNULL(GROUP_CONCAT(distinct(activity.name) SEPARATOR ', '),'не указано') as activity,
  IFNULL(GROUP_CONCAT(DISTINCT(mark.name) SEPARATOR ', '),'не указано') as marks,
  IFNULL(GROUP_CONCAT(DISTINCT(production.name) SEPARATOR ', '),'не указано') as production,
  IFNULL(GROUP_CONCAT(distinct(country.name) SEPARATOR ', '),'не указано') as country, result.name as result, result.id as resultId, company.comment,
  IF(CHAR_LENGTH(TRIM(IFNULL(company.stock, "")))>0,TRIM(IFNULL(company.stock, "Не указано")),"Не указано") as stock, company.interest, company.email,
  company.dispatch
FROM company
  LEFT JOIN activity_link as al on company.id = al.company_id AND al.deleted = 0
  LEFT JOIN activity on activity.id = al.activity_id
  LEFT JOIN production_link as pl on company.id = pl.company_id AND pl.deleted = 0
  LEFT JOIN production on production.id = pl.production_id
  LEFT JOIN country_link as cl on company.id = cl.company_id AND cl.deleted = 0
  LEFT JOIN country on country.id = cl.country_id
  LEFT JOIN result on company.result_id = result.id
  LEFT JOIN mark_link as ml on company.id = ml.company_id AND ml.deleted = 0
  LEFT JOIN mark on mark.id = ml.mark_id
WHERE company.deleted = 0
GROUP BY company.id
ORDER BY company.id DESC LIMIT 0, 30


Можно ли его как-то оптимизировать? Я уже все перепробовал, ставил индексы, пробовал переписывать его, но все тщетно. Мне пришлось временно удалить JOIN с таблицей mark_link, в итоге запрос стал выполняться примерно за 250 мс. Помогите пожалуйста, уже не знаю что делать =(.


Нет, его нельзя оптимизировать,
у него нет SARG-ов вообще (company.deleted = 0 не в счёт, неселективный).

обрабатывается всё. группируется все. Сортируется всё.
Затем -- БЕРЁТСЯ 30 ЗАПИСЕЙ!

Максимум что тут можно оптимизировать,
это JOIN-ы, на каждый надо посоздавать индексы в дочерних (правых) таблицах.


LEFT JOIN activity_link as al on company.id = al.company_id AND al.deleted = 0 -- на ( al.company_id, al.deleted )
LEFT JOIN activity on activity.id = al.activity_id -- на (activity_id)

и так далее.

Но, полагаю, что такие индексы уже есть, потому что это должны быть PK.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505423
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4. сделайте ЛИМИТ 0,30 в самом начале ОТДЕЛЬНО от всего остального
а потом навешивайте все остальное



Так зачем же LIMIT, можно просто выбрать нужные company_id, и сделать фильтр по ним в WHERE через IN
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505427
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrApsonПривет ребят. Такая проблема. Есть запрос, который агрегирует данные из 10 таблиц, в итоге он выполняется 95 секунд. Вот сам запрос:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT company.id, company.name as name, company.city as city, company.user_id, company.site as site, company.address as address,
  IFNULL(GROUP_CONCAT(distinct(activity.name) SEPARATOR ', '),'не указано') as activity,
  IFNULL(GROUP_CONCAT(DISTINCT(mark.name) SEPARATOR ', '),'не указано') as marks,
  IFNULL(GROUP_CONCAT(DISTINCT(production.name) SEPARATOR ', '),'не указано') as production,
  IFNULL(GROUP_CONCAT(distinct(country.name) SEPARATOR ', '),'не указано') as country, result.name as result, result.id as resultId, company.comment,
  IF(CHAR_LENGTH(TRIM(IFNULL(company.stock, "")))>0,TRIM(IFNULL(company.stock, "Не указано")),"Не указано") as stock, company.interest, company.email,
  company.dispatch
FROM company
  LEFT JOIN activity_link as al on company.id = al.company_id AND al.deleted = 0
  LEFT JOIN activity on activity.id = al.activity_id
  LEFT JOIN production_link as pl on company.id = pl.company_id AND pl.deleted = 0
  LEFT JOIN production on production.id = pl.production_id
  LEFT JOIN country_link as cl on company.id = cl.company_id AND cl.deleted = 0
  LEFT JOIN country on country.id = cl.country_id
  LEFT JOIN result on company.result_id = result.id
  LEFT JOIN mark_link as ml on company.id = ml.company_id AND ml.deleted = 0
  LEFT JOIN mark on mark.id = ml.mark_id
WHERE company.deleted = 0
GROUP BY company.id
ORDER BY company.id DESC LIMIT 0, 30


Можно ли его как-то оптимизировать? Я уже все перепробовал, ставил индексы, пробовал переписывать его, но все тщетно. Мне пришлось временно удалить JOIN с таблицей mark_link, в итоге запрос стал выполняться примерно за 250 мс. Помогите пожалуйста, уже не знаю что делать =(

Вообще, показательно идиотский запрос.

Полагаю, что он ещё и неправильный, поскольку группируются параллельно с JOIN-иненые несколько отношений один-ко-многим, проблему как раз подтверждают DISTINCT-ы внутри группировок.

МОжно, можно всю базу сджойнить, а потом DISTINC-том её сжать в одно уникальное значение, ну, будет работать 3 часа, -- не проблема :-)
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505434
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,

И как теперь быть?) что делать с этим запросом?
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505631
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivможно просто выбрать нужные company_id,

...так ЛИМИТ-ом же!...

...теже тестикулы, но еще и в гульфике WHERE ... IN (.....LIMIT 0,30)...

...я предлагаю сразу

SELECT
....
WHERE
(select company.* -- список нужных полей ......
from company
where WHERE company.deleted = 0
ORDER BY company.id DESC
LIMIT 0, 30) c

LEFT JOIN.......
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505680
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrApsonчто делать с этим запросом?
Верстай нечто вроде

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SELECT 
-- поля из основной таблицы
с0.id, 
с0.name, 
с0.city, 
с0.user_id, 
с0.site, 
с0.address,
с0.comment,
IF(CHAR_LENGTH(TRIM(IFNULL(с0.stock, "")))>0,TRIM(IFNULL(с0.stock, "Не указано")),"Не указано") as stock, 
с0.interest, 
с0.email,
с0.dispatch
-- расчётное поле из первого подзапроса
activity.activity 
-- поля из других подзапросов
-- 
FROM company с0
-- первый подзапрос
JOIN 
(
SELECT c1.id, COALESCE(GROUP_CONCAT(DISTINCT activity.name SEPARATOR ', '),'не указано') as activity,
FROM company c1
LEFT JOIN activity_link as al on c1.id = al.company_id AND al.deleted = 0
LEFT JOIN activity on activity.id = al.activity_id
WHERE c1.deleted = 0
GROUP BY c1.id
) activity ON activity.id = c0.id
-- JOIN другие подзапросы
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505682
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И подумай заодно - нужен ли реально DISTINCT в GROUP_CONCAT при такой организации.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505684
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И да - подзапросы отирают записей больше, чем лимит в основном запросе, так что и в подзапросах залимитируй.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505698
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
То бишь так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
JOIN 
(
SELECT c1.id, COALESCE(GROUP_CONCAT(DISTINCT activity.name SEPARATOR ', '),'не указано') as activity,
FROM company c1
LEFT JOIN activity_link as al on c1.id = al.company_id AND al.deleted = 0
LEFT JOIN activity on activity.id = al.activity_id
WHERE c1.deleted = 0
GROUP BY c1.id
LIMIT 0, 30
)
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505772
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А сортировочку-то добавить? а то оно тебе залимитит...
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505776
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
JOIN 
(
SELECT c1.id, COALESCE(GROUP_CONCAT(DISTINCT activity.name SEPARATOR ', '),'не указано') as activity,
FROM company c1
LEFT JOIN activity_link as al on c1.id = al.company_id AND al.deleted = 0
LEFT JOIN activity on activity.id = al.activity_id
WHERE c1.deleted = 0
GROUP BY c1.id
ORDER BY c1.id DESC
LIMIT 0, 30
)



И так каждый запрос?
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505777
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подзапрос*
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39505948
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну да... или тебе байтов жалко?
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39506831
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем ошибку выдает
#1054 - Неизвестный столбец 'c0.id' в 'on clause'
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39506858
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrApsonошибку выдает
#1054 - Неизвестный столбец 'c0.id' в 'on clause'Значит, где-то промарьяжился... проверь, что алиасы таблиц уникальны в пределах запроса и что все алиасы находятся в области их видимости.
...
Рейтинг: 0 / 0
SQL запрос выполняется 90 секунд
    #39506922
MrApson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем получился такой запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
SELECT 
-- поля из основной таблицы
com0.id, 
com0.name, 
com0.user_id, 
com0.site, 
com0.address,
com0.comment,
IF(CHAR_LENGTH(TRIM(IFNULL(com0.stock, "")))>0,TRIM(IFNULL(com0.stock, "Не указано")),"Не указано") as stock,
com0.interest,
com0.email,
com0.dispatch,
-- расчётное поле из первого подзапроса
activity.activity,
mark.marks,
production.production,
country.country,
result.name as result, result.id as resultId
-- поля из других подзапросов
-- 
FROM company com0
-- первый подзапрос
JOIN 
(
SELECT c1.id, COALESCE(GROUP_CONCAT(DISTINCT activity.name SEPARATOR ', '),'не указано') as activity
FROM company c1
LEFT JOIN activity_link as al on c1.id = al.company_id AND al.deleted = 0
LEFT JOIN activity on activity.id = al.activity_id
WHERE c1.deleted = 0
GROUP BY c1.id
ORDER BY c1.id DESC
LIMIT 0, 30
) activity ON activity.id = com0.id
JOIN 
(
SELECT c2.id, COALESCE(GROUP_CONCAT(DISTINCT mark.name SEPARATOR ', '),'не указано') as marks
FROM company c2
LEFT JOIN mark_link as ml on c2.id = ml.company_id AND ml.deleted = 0
LEFT JOIN mark on mark.id = ml.mark_id
WHERE c2.deleted = 0
GROUP BY c2.id
ORDER BY c2.id DESC
LIMIT 0, 30
) mark ON mark.id = com0.id
JOIN 
(
SELECT c3.id, COALESCE(GROUP_CONCAT(DISTINCT production.name SEPARATOR ', '),'не указано') as production
FROM company c3
LEFT JOIN production_link as pl on c3.id = pl.company_id AND pl.deleted = 0
LEFT JOIN production on production.id = pl.production_id
WHERE c3.deleted = 0
GROUP BY c3.id
ORDER BY c3.id DESC
LIMIT 0, 30
) production ON production.id = com0.id
JOIN 
(
SELECT c4.id, COALESCE(GROUP_CONCAT(DISTINCT country.name SEPARATOR ', '),'не указано') as country
FROM company c4
LEFT JOIN country_link as cl on c4.id = cl.company_id AND cl.deleted = 0
LEFT JOIN country on country.id = cl.country_id
WHERE c4.deleted = 0
GROUP BY c4.id
ORDER BY c4.id DESC
LIMIT 0, 30
) country ON country.id = com0.id
JOIN result on com0.result_id = result.id
LIMIT 0, 30


Запрос стал выполняться 0.007с. Спасибо огромное) Не думал, что джоины тоже надо лимитить.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / SQL запрос выполняется 90 секунд
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]