Перейти к содержимому


Тормоза при редактировании товара


  • Вы не можете ответить в тему
Сообщений в теме: 18

#1 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 17 June 2013 - 10:04 PM

У кого есть какие мысли или готовая истина на предмет "что быстрее" при пересохранении свойств товара в большой развесистой базе (цена, остальные поля - все, что сохраняется при нажатии кнопки "Сохранить" в страничке товара) -
штатный
UPDATE .PRODUCTS_TABLE. SET a=b.....WHERE productID=(int)$productID
в функции ProductUpdate (как-то так) или сначала
DELETE .PRODUCTS_TABLE. WHERE productID=(int)$productID
затем
INSERT .PRODUCTS_TABLE. SET a=b.....WHERE productID=(int)$productID
?
Сергей и так в курсе странной проблемы, а остальным вкратце опишу - при базе ShopCMS с ОЧЕНЬ большим (~1500) количеством категорий наблюдается странная тормознутость при сохранении отредактированного товара, 10-20секунд. Хотя там банально одна функция с одним SQL-запросом, которая и сохраняет (апдейтит) все значения за один запрос. И не видится НИКАКОЙ связи с таблицей категорий, т.е. совершенно не важно, сколько их там - десять или полторы тысячи.


PS. А что будет и может ли возникать тормознуть просто при частом изменений свойств товара? Т.е. примерно как в стареньких DBF-табличках, где записи помечались как "удаленные", т.е. пока не применялась специальная процедура сжатия - таблица росла и все более тормозила. Как по этой части у SQL-таблиц? нет ли каких процедур "сжатия"?

Глядя совсем уж в корень - ЧТО ДЕЛАЕТ процедура "Для оптимизации базы нажмите тут" в "Администрирование БД"? Понятно, что могу сам посмотреть, но мало ли кто уже разбирал и в двух словах объяснит?
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#2 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 17 June 2013 - 10:06 PM

Так это ты тот самый подрядчик который грешит на мой хостинг!?!?!? :angry:
  • 0

#3 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 17 June 2013 - 10:22 PM

Так это ты тот самый подрядчик который грешит на мой хостинг

Не совсем так. Я высказал предположение, что если раньше проблемы не было (или она была не настолько заметна), но она проявилась после смены хостинга, хотя ничего по коду не менялось... Дальше логика, как мне кажется, понятна и вполне справедлива :).

Я таки думаю, что проблема с SQL-таблицей товаров, которая часто редактируется по ценам (как мне подозревается довольно уверенно). Т.е. корень надо искать именно тут. Толи таблица товаров просто разрастается, толи делается менее оптимальной и тормозной (ключи?), но чудес не бывает и либо я чего-то не замечаю в простейшей процедуре, либо надо как-то оптимизировать (сжать? почистить? отсортировать? ) эту таблицу.

PS. Ну и несложно догадаться, что я понятия не имел о принадлежности хостинга. Не дошел я еще до уровня определения принадлежности и хорошести хостинга по IP-адресу :).

PPS. В общем, тут нужен совет кого-то, кто на порядок лучше меня разбирается в принципах устройства SQL-хранилища.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#4 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 17 June 2013 - 10:28 PM

Толи таблица товаров просто разрастается, толи делается менее оптимальной и тормозной (ключи?),

Думаю ты ошибаешься.
Я сделал копию полную сайта и переместил все товары в одну категорию, остальные категории удалил.
Все стало работать мгновенно, т.е. в таблице товаров ничего не изменилось, кроме айдишника в поле категории.

Нужно искать связь с таблицей категорий.... если она так влияет значит есть связь есть, просто видимо не так очевидна.

А на счет того что быстрее обновление запили или удаление и добавление, ИМХО логично что второй вариант дольше т.к. в первом 1 запрос а во втором 2, при этом второй (добавление) по структуре собственно практически повторяет обновление.
  • 0

#5 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 19 June 2013 - 01:25 PM

Т.е. надо лезть в admin.php и разбирать более четко

Тьфу ты, блин... А с чего, собственно, мной решилось, что тормоза происходят именно при сохранении товара? :)
Ведь после сохранения товара происходит перезагрузка страницы со списком товаров и категориями, где, как я подозреваю, и происходят те самые тормоза в силу полутора тысяч категорий, вот!
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#6 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 19 June 2013 - 02:27 PM

Почему тогда эти тормоза не происходят при первой загрузке страницы. Т.е. как только открываешь редактирование?
  • 0

#7 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 19 June 2013 - 04:24 PM

Или просто при обновлении страницы? тоже ведь обновляется быстро, хотя подгружаются все теже категории, а именно при сохранении идет какойто ступор.
  • 0

#8 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 19 June 2013 - 07:36 PM

Такс ну что, нашел я проблему.
Заключается она в следующем
При редактировании товара, а точнее при сохранении выполняется функция
update_psCount(1)

при том почему-то дважды
первый раз ее вызов в
function UpdateProduct

а второй раз ее вызов в admin.php после добавления или редактирования товара
if (CONF_UPDATE_GCV == '1') update_psCount(1);

Вот она то и вызывает этот ступор, т.к. идет пересчет кол-ва категорий и товаров в каждой категории.

После того как я закомментировал их сохраняться стало за пару секунд.

Гораздо правильнее конечно было бы добавить условие чтобы данная функция вызывалась только в случае изменения категории, а не каждый раз.
  • 0

#9 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 19 June 2013 - 07:54 PM

Прикольно. Талантливо таки код написан местами :).
Там в функции UpdateProduct последний параметр как раз запрещает-разрешает запуск пересчета. Это кроме установки в "Общих настройках" CONF_UPDATE_GCV. Но он нигде не используется, т.е. всегда =1 и не влияет. ИМХО, в данном случае (на этом сайте) решением будет просто выключить в "Общих настройках" галку "Показывать количество товаров в категориях", т.к. в используемом шаблоне это количество один хрен не показывается :).

PS. Хм... А оно там выключено. Т.е. функция update_psCount не должна вызываться. Или это ты уже выключил?
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#10 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 19 June 2013 - 07:59 PM

Нет я не выключал я закомментировал вызов этой функции.

А вот на счет показывать/не показывать я как-то не уверен что эта галка имеет смысл.
Дело в том что кол-во товаров в категории и кол-во подкатегорий используется не только в отображении, а и в менюшках насколько я помню, а может и еще где..... всего не помню.
  • 0

#11 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 19 June 2013 - 08:27 PM

Нет я не выключал я закомментировал вызов этой функции.

Хмм... CONF_UPDATE_GCV вообще имеет settings_groupID=1, т.е. не меняется штатно в настройках.

Ну, тогда вставить в select выбора категории в настройках товара onchahge="$('input[/'#category_changed/']').value=1" и добавить <input type="hidden" id="category_changed" name="category_changed" value="0"> и выполнять функцию update_psCount по условию if($_POST["category_changed"] == 1)
Я бы сделал как-то так.

PS. Надо таки сделать что-то типа "Расширенные настройки". А то там куча настроек с settings_groupID=1, с названиями и описаниями, но даже не посмотреть, что это и на что влияет :).
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#12 R.Sergey

    Администратор

  • Администраторы
  • 2810 сообщений
Репутация: 332
Мастер

Отправлено 19 June 2013 - 08:30 PM

А я бы чтобы не добавлять еще одну переменную сравнивал бы значение ID категории текущей с ID которое передается в пост и если они разные тогда бы делал пересчет..... ну как-то так, извините если непонятно выражаюсь я тут пивком балуюсь )))
  • 0

#13 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 19 June 2013 - 08:34 PM

сравнивал бы значение ID категории текущей с ID которое передается в пост

Да, так заметно изящнее будет.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#14 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 12 August 2013 - 02:25 AM

Такс ну что, нашел я проблему. Заключается она в следующем При редактировании товара, а точнее при сохранении выполняется функция update_psCount(1) при том почему-то дважды первый раз ее вызов в function UpdateProduct а второй раз ее вызов в admin.php после добавления или редактирования товара if (CONF_UPDATE_GCV == '1') update_psCount(1); Вот она то и вызывает этот ступор, т.к. идет пересчет кол-ва категорий и товаров в каждой категории. После того как я закомментировал их сохраняться стало за пару секунд. Гораздо правильнее конечно было бы добавить условие чтобы данная функция вызывалась только в случае изменения категории, а не каждый раз.

Я решил немного по другому, попроще в реализации. Функция вызывается как и раньше (по поводу и без повода), это я копать не стал, а просто минимизировал количество запросов. Штатно там на каждую категорию идет восемь (!) SQL-запросов. Рекурсивно, обходя все дерево категорий. Т.е. при 1000 категорий получим 8тыс запросов при сохранении товара. Точнее, даже 16тыс (см. про вызов функции два раза).
Прилагаемый ниже код для пересчета любого количества категорий выполняет четыре :) запроса, если это не первый пересчет в жизни сайта. На сайте с 1500 категорий ускорение действительно очень заметно.


Установка:

В файле category_functions.php

1. в функции update_psCount

строку


update_pCount($parent);


заменяем на


update_pCount_new($parent);


2. куда-нибудь рядом добавляем две функции


function update_sCount_new($parent, $counts = array(1 => array ('subcats' => 0,'admin_count' => 0,'customer_count' => 0)))
{
global $mc;
foreach (array_keys ($mc,(int)$parent) as $val)
{
$counts[$val]['subcats'] = count(array_keys($mc, $val));
$counts[$val]['admin_count'] = 0;
$counts[$val]['customer_count'] = 0;
if ($counts[$val]['subcats']) $counts = update_sCount_new($val,$counts);
}
return $counts;
}

function update_pCount_new($parent)
{
global $fc;
$qstr = array(
"SELECT categoryID, COUNT(*) AS admcount, COUNT(NULLIF(enabled,0)) AS count FROM ".PRODUCTS_TABLE." GROUP BY categoryID",
"SELECT pc.categoryID, count(*) AS admcount, COUNT(NULLIF(enabled,0)) AS count FROM ".CATEGORIY_PRODUCT_TABLE." AS pc JOIN ".PRODUCTS_TABLE." USING (productID) GROUP BY pc.categoryID");
$counts = update_sCount_new($parent);
foreach ($qstr as $str)
{
$data = db_query($str);
while ($row=db_fetch_assoc($data))
{
$categoryID = (int)$row['categoryID'];
while ($categoryID)
{
$counts[$categoryID]['admin_count'] += (int)$row['admcount'];
$counts[$categoryID]['customer_count'] += (int)$row['count'];
$categoryID = $fc[$categoryID]['parent'];
}
}
}
$data = db_query("SELECT categoryID, subcount, products_count, products_count_admin FROM ".CATEGORIES_TABLE);
while ($row = db_fetch_assoc($data))
{
$categoryID = (int)$row['categoryID'];
if ((int)$row['subcount'] != $counts[$categoryID]['subcats'] || (int)$row['products_count'] != $counts[$categoryID]['customer_count'] || (int)$row['products_count_admin'] != $counts[$categoryID]['admin_count'])
db_query("UPDATE ".CATEGORIES_TABLE." SET subcount=".$counts[$categoryID]['subcats'].", products_count=".$counts[$categoryID]['customer_count'].", products_count_admin=".$counts[$categoryID]['admin_count']." WHERE categoryID=$categoryID");
}
}

  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#15 mrTimex

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 82 сообщений
Репутация: -2
Начинающий

Отправлено 19 August 2013 - 12:59 PM

вот в ветке про расширенный поиск я эту проблему и пытался описать. После применения инструкции от Badisoft запросы примерно стали занимать по 5-7 сек, а были по 10-15. хотя все равно очень долго.
  • 0

#16 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 19 August 2013 - 02:20 PM

вот в ветке про расширенный поиск я эту проблему и пытался описать.

Не очень понимаю связь между расширенным поиском (который в клиентской части) и скоростью сохранения товаров в админке.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#17 mrTimex

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 82 сообщений
Репутация: -2
Начинающий

Отправлено 19 August 2013 - 02:25 PM

тормоза у меня не в клиентской части а как раз в админской. когда они появились точно сказать не могу, т.к я сам в товары не лез раньше, это работа манагеров. а теперь пока тестирую поиск сам создавал товары и заметил
  • 0

#18 badisoft

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 5075 сообщений
Репутация: 786
Мастер

Отправлено 18 April 2014 - 09:32 PM

update: исправил ошибку. Влияла ошибка только на появление записи в "Статистике ошибок" про неверную SQL-команду при каждом нажатии "Сохранить" в списке товаров, более ни на что.

Надо заменить

function update_sCount_new($parent, $counts = array())

на

function update_sCount_new($parent, $counts = array(1 => array ('subcats' => 0,'admin_count' => 0,'customer_count' => 0)))

в исходнике уже исправлено.
  • 0
http://cpu.badisoft.ru (тестовый сайт), http://badisoft.ru (модули)

#19 kery

    Продвинутый пользователь

  • Assistent vsupport.club
  • PipPipPip
  • 134 сообщений
Репутация: 17
Начинающий

Отправлено 08 May 2014 - 05:43 PM

лазил по просторам инета и нашел еще один способ отключения пересчета,
Пересчет товаров при каждом сохранении можно отключить, но ответственный за это параметр скрыт в базе данных. Включить отображение параметра можно с помощью следующего SQL запроса:
UPDATE ваш_префикс_settings SET settings_groupID=2 WHERE settings_constant_name='CONF_UPDATE_GCV' LIMIT 1

После в общих настройках появится Автоматически обновлять количество товаров в категориях (в администрации)
  • 1