Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / SQL запрос выполняется 90 секунд / 22 сообщений из 22, страница 1 из 1
14.08.2017, 16:15
    #39505073
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
Привет ребят. Такая проблема. Есть запрос, который агрегирует данные из 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
14.08.2017, 16:51
    #39505101
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
MrApson,

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

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

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

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

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

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

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

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

()
...
Рейтинг: 0 / 0
14.08.2017, 18:50
    #39505233
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
Сейчас уеду на час-полтора, приеду и распишу.
...
Рейтинг: 0 / 0
15.08.2017, 07:48
    #39505358
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
Я бы каждую группу (company + data_link + data) убрал в отдельный подзапрос, чем избавился от DISTINCT.
...
Рейтинг: 0 / 0
15.08.2017, 09:48
    #39505422
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
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
15.08.2017, 09:51
    #39505423
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
4. сделайте ЛИМИТ 0,30 в самом начале ОТДЕЛЬНО от всего остального
а потом навешивайте все остальное



Так зачем же LIMIT, можно просто выбрать нужные company_id, и сделать фильтр по ним в WHERE через IN
...
Рейтинг: 0 / 0
15.08.2017, 09:55
    #39505427
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
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
15.08.2017, 10:03
    #39505434
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
MasterZiv,

И как теперь быть?) что делать с этим запросом?
...
Рейтинг: 0 / 0
15.08.2017, 14:24
    #39505631
javajdbc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
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
15.08.2017, 15:03
    #39505680
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
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
15.08.2017, 15:04
    #39505682
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
И подумай заодно - нужен ли реально DISTINCT в GROUP_CONCAT при такой организации.
...
Рейтинг: 0 / 0
15.08.2017, 15:05
    #39505684
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
И да - подзапросы отирают записей больше, чем лимит в основном запросе, так что и в подзапросах залимитируй.
...
Рейтинг: 0 / 0
15.08.2017, 15:13
    #39505698
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
То бишь так?
Код: 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
15.08.2017, 16:17
    #39505772
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
А сортировочку-то добавить? а то оно тебе залимитит...
...
Рейтинг: 0 / 0
15.08.2017, 16:21
    #39505776
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
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
15.08.2017, 16:21
    #39505777
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
Подзапрос*
...
Рейтинг: 0 / 0
15.08.2017, 20:56
    #39505948
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
Ну да... или тебе байтов жалко?
...
Рейтинг: 0 / 0
17.08.2017, 13:54
    #39506831
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
В общем ошибку выдает
#1054 - Неизвестный столбец 'c0.id' в 'on clause'
...
Рейтинг: 0 / 0
17.08.2017, 14:24
    #39506858
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
MrApsonошибку выдает
#1054 - Неизвестный столбец 'c0.id' в 'on clause'Значит, где-то промарьяжился... проверь, что алиасы таблиц уникальны в пределах запроса и что все алиасы находятся в области их видимости.
...
Рейтинг: 0 / 0
17.08.2017, 15:13
    #39506922
MrApson
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
SQL запрос выполняется 90 секунд
В общем получился такой запрос
Код: 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
Форумы / MySQL [игнор отключен] [закрыт для гостей] / SQL запрос выполняется 90 секунд / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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