![]() |
|
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]()
|
|
| Ramoff |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 25.12.2012 Репутация: нет Всего: нет |
Всем привет)
Есть у меня таблица в базе MySQL с 1600 записей типа: ID | name | surname | price | good | quantity Выполняется скрипт PHP, который должен вывести таблицу с анализом по каждому клиенту типа (я схематично опишу):
Из-за того, что, собственно, данных много, а в таблице полей порядка сотни на самом деле, а записей порядка 1 600 штук, то при уровне вложенности таких запросов получается порядка 600 MySQL запросов. Естесственно, что это ведёт к повышенному потреблению RAM (до 25 мегов в пике) и процессора. Пусть сервер и мощный, но всегда надо стараться всё оптимизировать. Вопрос в одном: как при такой конструкции уменьшить количество запросов? Вместо * в запросе я обычно указываю название полей, стараясь не загружать все данные махом. Буду рад любым комментариям. Добавлено через 7 минут и 50 секунд А что самое интересное — время работы скрипта может варьироваться от 0,4 секунды до 70. Добавлено через 10 минут и 31 секунду А может ли влиять на время обработки влиять наличие индекса полнотекстового у таблицы на часто используемые поля? |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Во-первых, все запросы нужно анализировать с помощью EXPLAIN и смотреть, юзается ли индекс.
Тут не совсем понятно вот что: `table` в обоих запросах одна и та же? Если нет - можно объединить запросы в один через left join. Если одна и та же, то получается фактически второй запрос выбирает все данные по товару в цикле всех товаров (то есть все данные всех товаров). А значит его можно выполнить один раз за пределами цикла и дальше обращаться к static cached данным. |
|||
|
||||
| Ramoff |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 25.12.2012 Репутация: нет Всего: нет |
Aliance, по EXPLAIN я сейчас буду изучать.
`table` — действительно везде одна и та же. И в конце запроса первого самого стоит GROUP, чтобы исключить вывод повторяющихся данных. А это значит, что не получится избежать второго цикла, где происходит как раз уточнение данных первого запроса... |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
По факту получается, что первым запросом ты получаешь массив уникальный GOOD_ID, а во втором запросе по каждому отдельно получаешь. Что мешает сделать два цикла. Первый запрос - заполняем массив $good_ids = array() этими значениями, второй цикл - по результатам запроса №2, только с условием good IN(ID1, ID3, ID3)
|
|||
|
||||
| Ramoff |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 25.12.2012 Репутация: нет Всего: нет |
Aliance, а можно небольшой пример абстрактный? Я почему-то "догнать" не могу этот метод.
|
|||
|
||||
| Arantir |
|
|||
|
Рыбак без удочки ![]() ![]() Профиль Группа: Участник Сообщений: 960 Регистрация: 18.11.2012 Репутация: нет Всего: 55 |
Ramoff, я бы вообще предложил сначала выбрать все нужные данные (которые вы для каждого good выбираете) через
Это сократит все до 2-х запросов. Да, конечно, придется сразу держать много данных, но это все же эффективнее за 600 запросов. Об этом, собственно, Aliance, выше писал. К вышесказанному: Выберите все данные вышеприведенным запросом, потом в цикле поместите все строки в массив. После чего дальше вы сможете выбирать для каждого good его строки просто сравнивая в цикле $array[i]['good'] массива всех строк с текущим good. Кроме того, массив отсотрирован, так что, после первого попавшегося подходящего good, следующий неподходящий означает, что подходящих больше нет и цикл текущего good можно завершать, сократив таким образом количество операций. При желании для всего этого можно даже написать бинарный поиск, только надо предусмотреть множественность результатов поиска. Это сообщение отредактировал(а) Arantir - 25.12.2012, 22:45 -------------------- interface Жопа { // ATTENTION: has to be implemented by every class of the project for proper project work } |
|||
|
||||
| Ramoff |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 25.12.2012 Репутация: нет Всего: нет |
Arantir, теперь всё стало ясно! Спасибо большое! Сейчас буду экспериментировать! Хотя до последнего надеялся, что можно сформировать какой-то сложный MySQL запрос. Но и это неплохо.
|
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | PHP: Базы Данных | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |