Форум программистов, компьютерный форум, киберфорум
MySQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
105 / 104 / 29
Регистрация: 15.01.2011
Сообщений: 515

Оптимизация вложенного SELECT

28.11.2016, 08:21. Показов 1418. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Помогите, пожалуйста переписать запрос так, чтобы он меньше нагружал БД.
В одной БД есть две таблицы: table_list и table_stat.
Вот состав таблиц:
table_list:
ID_field (уникальное)
Int_field (неуникальное)
table_stat:
ID_field (неуникальное)
Value_field (неуникальное)
Нужно просуммировать значения Value_field в table_stat для каждого ID_field из table_list. ID_field в обеих таблицах связан внешним ключом.
Мой вариант такой:
MySQL
1
2
3
4
5
6
7
8
9
SELECT table_list.ID_field,    
 
  (SELECT SUM(table_stat.Value_field) 
  FROM table_stat 
  WHERE table_stat.ID_field=table_list.ID_field     
  ) AS summa,    
   
FROM table_list
WHERE table_list.Int_field = *some_value*
Можно ли как-то оптимизировать этот запрос?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.11.2016, 08:21
Ответы с готовыми решениями:

Как сделать LIMIT для вложенного цикла SELECT
Приветствую! У меня есть вот такой запрос: SELECT wp_rg_lead.date_created, wp_rg_lead_detail.* FROM wp_rg_lead JOIN...

Оптимизация запроса SELECT COUNT
Всем привет! Как решить вопрос с нагрузкой и скоростью выполнения запроса SELECT COUNT, если в таблице больше 50 млн записей. Есть варианты...

Оптимизация запроса SELECT WHERE
Здраствуйте! У нас есть PostgreSQL 9.6.6 и имеется таблица с ежедневными данными от датчиков для много станций. codigo_estacao...

11
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
28.11.2016, 10:07
Цитата Сообщение от WoodHead Посмотреть сообщение
Можно ли как-то оптимизировать этот запрос?
JOIN + GROUP BY
0
105 / 104 / 29
Регистрация: 15.01.2011
Сообщений: 515
28.11.2016, 10:12  [ТС]
Grossmeister, был бы вам признателен, если бы вы написали пример запроса. А то непонятно, как применять эти операторы.
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
28.11.2016, 10:16
SQL
1
2
3
4
5
SELECT T1.fld1, SUM(T2.fld2)
FROM tab1 T1,
     tab2 T2
WHERE T1.id1 = T2.id2
GROUP BY T1.fld1
1
105 / 104 / 29
Регистрация: 15.01.2011
Сообщений: 515
29.11.2016, 12:00  [ТС]
Grossmeister, а как оценить, насколько новый запрос лучше старого? По времени выполняются одинаково. Правда, в профилеровщике 99% занимает sending data. Непонятно, куда смотреть.

Добавлено через 18 часов 46 минут
Столкнулся с тем, что если добавить условие по выбору данных во вложенный запрос, то оптимизированный запрос уже работает не так, как надо.
Например, исходный запрос с подзапросом с дополнительным условием по полю даты:
MySQL
1
2
3
4
5
6
7
8
9
10
11
SELECT table_list.ID_field,    
 
  (SELECT SUM(table_stat.Value_field) 
  FROM table_stat 
  WHERE table_stat.ID_field=table_list.ID_field 
  -- это условие, которое добавилось
  AND table_stat.Date_field = CURDATE()    
  ) AS summa,    
   
FROM table_list
WHERE table_list.Int_field = *some_value*
Если вложенный запрос не содержит строк, то возвращается всё-равно полный набор данных поля ID_field из таблицы table_list, а также рядом есть поле summa, значение которого во всех строках равно NULL.

Если же сделать так:
MySQL
1
2
3
4
5
6
SELECT table_list.ID_field, SUM(table_stat.Value_field) AS summa    
FROM table_list, table_stat
WHERE table_stat.ID_field=table_list.ID_field
AND table_list.Int_field = *some_value*
AND table_stat.Date_field = CURDATE()
GROUP BY table_list.ID_field
В этом случае если нет записей за текущую дату, то в результат запроса не будет содержать ни одной записи.
Можно ли в этом случае улучшить запрос с вложенным запросом?
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
29.11.2016, 15:04
Цитата Сообщение от WoodHead
Если вложенный запрос не содержит строк, то возвращается всё-равно полный набор данных поля ID_field из таблицы table_list
Так и должно быть
Цитата Сообщение от WoodHead Посмотреть сообщение
В этом случае если нет записей за текущую дату, то в результат запроса не будет содержать ни одной записи.
Так и должно быть

Надо то как?
0
105 / 104 / 29
Регистрация: 15.01.2011
Сообщений: 515
29.11.2016, 15:56  [ТС]
Grossmeister, первый вариант запроса (с вложенным запросом) приводит к большой нагрузке на БД. Ищу способ переписать запрос так, чтобы нагрузка снизилась. Но не могу написать оптимальный эквивалент запроса, опыта не хватает. Второй вариант (с GROUP BY) - это моя попытка написать эквивалент, но результат, увы, получается другой (не такой, как в первом варианте).
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
29.11.2016, 16:00
Цитата Сообщение от WoodHead Посмотреть сообщение
Ищу способ переписать запрос так, чтобы нагрузка снизилась.
Это я понял. Но в предыдущем посте ты написал, что если добавить дату и проч., то результаты в 2 вариантах тебя не устроили. Поэтому я и спросил, а чем не устроили. Какой результат д.б. по замыслу?
0
105 / 104 / 29
Регистрация: 15.01.2011
Сообщений: 515
29.11.2016, 16:27  [ТС]
Grossmeister, вот пример запроса, который выдаёт правильный результат:
MySQL
1
2
3
4
5
6
7
8
9
10
11
SELECT table_list.ID_field,    
 
  (SELECT IFNULL(SUM(table_stat.Value_field),0) 
  FROM table_stat 
  WHERE table_stat.ID_field=table_list.ID_field 
  -- это условие, которое добавилось
  AND table_stat.Date_field = CURDATE()    
  ) AS summa,    
   
FROM table_list
WHERE table_list.Int_field = *some_value*
В первом сообщении темы я проморгал условие по дате, а в сообщении №5 исправился.
Проблема: этот запрос приводит к превышению допустимой нагрузки на БД у хостера. Есть два варианта: либо перейти на более дорогой тариф, либо оптимизировать запросы к БД. Везде пишут, что если перейти от вложенных запросов к соединениям, то нагрузка на БД снизится. Проблема в том, что у меня не получается оптимизировать этот запрос.
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
29.11.2016, 16:43
Цитата Сообщение от WoodHead
Везде пишут, что если перейти от вложенных запросов к соединениям, то нагрузка на БД снизится
Ну так мы уже обсудили вариант с соединением (JOIN). Что должен возвращать запрос с соединением, если по дате нет ни одной записи?
0
105 / 104 / 29
Регистрация: 15.01.2011
Сообщений: 515
29.11.2016, 17:05  [ТС]
Цитата Сообщение от Grossmeister Посмотреть сообщение
Что должен возвращать запрос с соединением, если по дате нет ни одной записи?
Должен вернуть 2 столбца. В первом столбце содержатся строки со значением ID_field, а во втором - значения сумм значений Value_field (если таких значений нет, то возвращается 0). На количество записей в итоговой таблице влияет только условие
MySQL
1
WHERE table_list.Int_field = *some_value*
С JOIN как-то не получается. Условие по дате может вернуть пустой набор.
0
4217 / 3059 / 583
Регистрация: 21.01.2011
Сообщений: 13,203
30.11.2016, 09:31
Цитата Сообщение от WoodHead Посмотреть сообщение
С JOIN как-то не получается
Почитай про LEFT JOIN (внешнее соединение)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.11.2016, 09:31
Помогаю со студенческими работами здесь

Оптимизация кода с помощью конструкций Case Select
написал данный код Private Sub CommandButton1_Click() Unload Me UserForm4.Show If OptionButton1.Value = True Then ...

Типы оптимизация: черная оптимизация, серая оптимизация и белая оптимизация
Много много лет назад, на заре становления профессии "оптимизатора" в какой то умной книжке был создан миф. Это миф о цветовой индефикации...

Оптимизация методом Ньютона (нахождение точки минимума). Оптимизация кода
MATLAB только начал осваивать. Попытался реализовать нахождение точки минимума методом Ньютона для функции 2*X12 - X1*X2 + 3*X22 -...

Как изменить значение одного select-а при изменении другого select-а?
Добрый день! Подскажите как изменить значение select при изменении другого select. первый: <select id="options"> ...

Как при изменении одного <select> подгрузить в другой <select> данные...
Как при изменении одного &lt;select&gt; подгрузить в другой &lt;select&gt; данные... пример: с марками машин. При выборе 'TOYOTA'...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru