Rapida Форк на базе simpla 2.3.8

Там 5 копеек, там еще 5 - пускай были бы.
Как можно стремиться к быстродействию и сидеть на рнр5?..
 
Там 5 копеек, там еще 5 - пускай были бы.
Как можно стремиться к быстродействию и сидеть на рнр5?..

Если бы совместимость была ценой быстродействия, я бы плюнул на php5, но тут такая фигня, которая точно того не стоит.
Судите сами, вот так функция, которая была с использованием type hinting и она же сейчас, но без type hinting.
Так было:
Код:
public function get_cache_nosql(string $keyword, bool $as_array = null)
    {
        if (is_null($as_array)) {
            $as_array = true;
        }
       $file_path = $this->getFilePath($keyword);
        if(!file_exists($file_path)) {
            dtimer::log(__METHOD__. ' file_exists check. not found '.$file_path);
            return null;
        }

        $content = file_get_contents($file_path);
        // check if codepage isset transcode from codepage to utf8
        if (!empty(self::$config['codepage'])) {
            $content = iconv(self::$config['codepage'], "utf-8", $content);
        }

        $array = $this->decode($content, $as_array);

        return $array;
    }

Так стало:
Код:
    public function get_cache_nosql($keyword,$as_array = null)
    {
        //проверка типов аргументов (вместо type hinting)
        if(!is_string($keyword) || !is_bool($as_array)){
             trigger_error(__METHOD__ . ' ' . __LINE__ . 'wrong argument type');
              return false;
        }
        if (is_null($as_array)) {
            $as_array = true;
        }
       $file_path = $this->getFilePath($keyword);
        if(!file_exists($file_path)) {
            dtimer::log(__METHOD__. ' file_exists check. not found '.$file_path);
            return null;
        }

        $content = file_get_contents($file_path);
        // check if codepage isset transcode from codepage to utf8
        if (!empty(self::$config['codepage'])) {
            $content = iconv(self::$config['codepage'], "utf-8", $content);
        }

        $array = $this->decode($content, $as_array);

        return $array;
    }
 
версия 5.6 стояла. Ок. сегодня переставлю!
 
в Simpla 1.X было поле "Название товара/категории в единственном числе".
Возможно вам стоить добавить такое поле, которое будет автоматически заполнятся при создании товара.

И еще - почти все фильтры в API работают как
Код:
if(!empty($filter['category_id']))
если в них передается параметр как 0 - то они не срабатывают.
 
в Simpla 1.X было поле "Название товара/категории в единственном числе".
Возможно вам стоить добавить такое поле, которое будет автоматически заполнятся при создании товара.

И еще - почти все фильтры в API работают как
Код:
if(!empty($filter['category_id']))
если в них передается параметр как 0 - то они не срабатывают.

Спасибо за идею, сделаю.

Я для этого свою функцию empty_ запилил, в ней 0 - false
<-------------- добавлено через 478 сек. -------------->
По поводу api симплы, очень удивило, что никто из разработчиков шабов или форков не менял там ничего принципиально. А там очень прилично переписать придется. Начиная с основы - класс db.
Почти все функции сейчас там переписываю. Надеюсь толк будет.
 
А не в курсе как устроена логика с фильтрами. на окай большая проблема. если товаров 10, то яндекс найдет их более 1000 на страницах со свойствами, причем страницы окажутся пустыми. В общем окай генерит несуществующие страницы с отсутствующими товарами из свойств.
 
А не в курсе как устроена логика с фильтрами. на окай большая проблема. если товаров 10, то яндекс найдет их более 1000 на страницах со свойствами, причем страницы окажутся пустыми. В общем окай генерит несуществующие страницы с отсутствующими товарами из свойств.
Я про это и говорю, такое получается из-за заложенной в симплу логики работы фильтров свойств товаров, в окее ничего не меняли.

Эту проблему я уже решил - все получилось. Но дело в том, что для новой схемы работы, которую я придумал, требуется выполнение сразу 3 аналогичных запросов к БД. Если просто перенести эту логику работы, не изменяя структуру БД, система станет очень заметно тормозить.
Чтобы обеспечить скорость работы, я поменял механизм хранения свойств в БД.

Если упростить схема такая:
есть 3 таблицы:
s_products с товарами
s_features с названиями свойств товаров
s_options со значениями свойств товаров

Если у нас есть 100 тыс. товаров и в них по 30 свойств в каждом, то в таблице s_options будет 3 млн. записей.

При открытии любого раздела на сайте выполняется запрос к таблице s_options
Код:
SELECT po.product_id, po.feature_id, po.value, count(po.product_id) as count
FROM s_options po
INNER JOIN s_products p ON p.id=po.product_id AND visible=1
INNER JOIN s_products_categories pc ON pc.product_id=po.product_id AND pc.category_id in('1')
WHERE 1 AND po.feature_id in('2','4','5')
GROUP BY po.feature_id, po.value
ORDER BY value=0, -value DESC, value

А есть еще запрос count_products, get_products, во всех этих запросах происходит обращение к таблице s_options в которой 3 млн. записей. В итоге скорость работы системы оставляет желать лучшего.

Система кеширования в rapida как раз работает с этими 3 самыми частыми и самыми сложными запросами, в результате повторное выполнение этих функций выполняется в фоновом режиме через планировщик cron, а для пользователя данные выдает кеш.

Для нормальной работы фильтров свойств этого недостаточно.

Я уже испробовал схему, где данные свойств хранятся в 1 горизонтальной таблице.
product_id, 1, 2, 3, 4, 5, где в столбцах хранятся данные соответствующих свойств товаров. Скорость работы хорошая и все было бы хорошо, если бы не 2 проблемы.

1. Самая главная - Mysql не позволяет создать индексы больше, чем на 63 столбца 1 таблицы. Без индексов поиск по таблице становится очень долгим.
2. Размер такой таблицы получается очень приличным, потому что надо для каждого товара зарезервировать места для всех свойств, которые вообще существуют в системе. Предположим у 1 товара 100 свойств, а у остальных 999 товаров только 2, места придется занять для 100 свойств у 1000 товаров.

Хочу сейчас попробовать 2 разные схемы и сравнить их по скорости.
1. Каждое свойство товара лежит в отдельной таблице.
2. Отдельная таблица для всех уникальных значений свойств товаров. Свойства чаще повторяются, поэтому таблица будет небольшая. Отдельная горизонтальная таблица со всеми свойствами товаров, но хранится в ней будут не значения, а только id соответствующих свойств. Проблема размера таблицы решается, Остается только ограничение на 63 индекса в MYSQL.

Вторая схема скорее всего будет заметно быстрее за счет того, что все будет лежать в 1 таблице, но надо проверить.
 
Последнее редактирование:
1. Самая главная - Mysql не позволяет создать индексы больше, чем на 63 столбца 1 таблицы. Без индексов поиск по таблице становится очень долгим.
Не смог найти кто, но одни умельцы с большим количеством свойств "разрезали вертикально" такие таблицы на несколько, и джойнят их по первичному ключу. По этим таблицам они построили покрывающие/составные индексы.
В другом треде я написал, что если по одной такой таблице произойдет обновление, это сбросит только часть кеша мускула, где эта таблица задействована в запросе. Вторая особенность такого вертикального "реза" - таблицы получаются меньше, и работают по этой причине быстрее. Мускул работает с памятью, поделенной на страницы. Если одна строка будет влезать в одну страницу - это вообще шикарно. А это как раз достигается маленькими "в ширину" таблицами.
Но тут можно упереться в другое ограничение - количество памяти. Есть запросы, которые показывают количество места под самими данными и под индексами. Иногда индексы начинают по размеру приближаться к размерам данных. Обслуживание индексов - на это БД также тратит время, поэтому много индексов плохо. И индексы быстро работают, пока умещаются в память. Как только перестают - идут дисковые операции, и скорость падает. Поэтому не надо обольщаться, если все круто работает. На определенном размере перестанет :)
2. Какой engine из мускула используется?
3. Делали EXPLAIN EXTENDED "ваш запрос"?
 
нужно на REST переходить. Полностью. Я кстати уже в этом деле дергался) заканчивать лень)
 
Иногда индексы начинают по размеру приближаться к размерам данных. Обслуживание индексов - на это БД также тратит время, поэтому много индексов плохо. И индексы быстро работают, пока умещаются в память.
Поэтому индексы лучше навешивать на одно поле типа int (bigint). Так они занимают не более 8байт. А в поле хранить преобразованный в десятичное число md5-хеш (я усекаю до 15 символов) нужных вам столбцов. По много миллионной базе запросы практически мгновенные получаются.
<-------------- добавлено через 1730 сек. -------------->
С кешем я уже так и сделал, только взял md4, а не md5 (пошустрее по тестам) и в базу их пишу bin(16), но твой вариант сделать десятичным числом и урезать до 15 символов кажется еще короче выходит?
Фишка в том что число будет занимать максимум 8 байт, как и его индекс. md5 и так самый быстрый, а нативного md4 в php по моему нет. урезаю до 15 символов, чтоб не было проблем с конвертацией base_convert, поле должно быть BIGINT UNSIGNED.
 
Назад
Сверху