Эффективность вызова базы данных Codeigniter - PullRequest
2 голосов
/ 11 ноября 2011

Это вопрос эффективности / передовой практики. Надеемся получить обратную связь по производительности. Любой совет с благодарностью.

Так что вот небольшой фон в том, что у меня есть настройки. Я использую codeigniter, базовая настройка очень похожа на любые другие отношения продукта. Основные таблицы: бренды, продукты, категории. Поверх этих таблиц необходимо установить листы, маркетинговые материалы и цвета.

Я создал несколько таблиц отношений: Brands_Products Products_Colors Products_Images Products_Sheets

У меня также есть таблица Categories_Relationships, в которой хранятся все отношения с категориями. Установочные листы и т. Д. Могут иметь свои собственные категории, но я не хотел определять разные таблицы отношений категорий для каждого типа, потому что я не думал, что это будет очень расширяемым.

На переднем крае я сортирую по брендам и категориям.

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

То, что я сейчас написал, работает нормально и сортируется, но я думаю, что могу улучшить производительность, поскольку для возврата запроса требуется некоторое время. Сейчас возвращается около 45 предметов. Вот моя первая функция, она захватывает все продукты и информацию.

Работает, сначала выбирая все продукты и объединяя информацию о своем бренде. затем, просматривая результат, я устанавливаю основную информацию, но для образов категорий и установок я использую функции, которые возвращают каждый из уважаемых элементов.

public function all()
    {
        $q = $this->db
                    ->select('*')
                    ->from('Products')
                    ->join('Brands_Products', 'Brands_Products.product_id = Products.id')
                    ->join('Brands', 'Brands.id = Brands_Products.brand_id')
                    ->get();

        foreach($q->result() as $row)
        {
            // Set Regular Data
            $data['Id'] = $row->product_id;
            $data['Name'] = $row->product_name;
            $data['Description'] = $row->description;
            $data['Brand'] = $row->brand_name;
            $data['Category'] = $this->categories($row->product_id);
            $data['Product_Images'] = $this->product_images($row->product_id);
            $data['Product_Installs'] = $this->product_installs($row->product_id);
            $data['Slug'] = $row->slug;


            // Set new item in return object with created data
            $r[] = (object)$data;
        }


        return $r;
    }

Вот пример одной из функций, используемых для получения отдельных частей.

private function product_installs($id)
    {
        // Select Install Images 
        $install_images = $this->db
                  ->select('*')
                  ->where('product_id', $id)
                  ->from('Products_Installs')
                  ->join('Files', 'Files.id = Products_Installs.file_id')
                  ->get();

        // Add categories to category object
        foreach($install_images->result() as $pImage)
        {
            $data[] = array(
                        'id' => $pImage->file_id, 
                        'src' => $pImage->src,
                        'title' => $pImage->title,
                        'alt' => $pImage->alt
                        );
        }

        // Make sure data exists
        if(!isset($data))
        {
            $data = array();
        }

        return $data;
    } 

Итак, еще раз просто посмотрим на советы о том, какой самый эффективный и лучший способ сделать это. Я очень ценю любые советы или информацию.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2011

Вы можете попробовать это:

  1. Запрос всех продуктов
  2. Получить все идентификаторы продуктов с шага 1
  3. Запрос всех установочных образов с идентификатором продукта из шага 2, отсортированный по идентификатору продукта
  4. Переберите продукты с шага 1 и добавьте результаты с шага 3

Это займет от 46 запросов (для 45 продуктов) до 2 запросов без каких-либо дополнительных объединений.

Вы также можете использовать Кэширование запросов CodeIgniter для дальнейшего повышения производительности, если стоит время написать код для сброса кэша при обновлении данных.

Выполнение большей работы в PHP обычно лучше, чем выполнение работы в MySQL с точки зрения масштабируемости. Вы можете легко масштабировать PHP с помощью балансировщиков нагрузки и веб-серверов. Масштабировать MySQL не так просто из-за проблем с параллелизмом.

0 голосов
/ 11 ноября 2011

Я думаю, что ваш подход правильный. Есть только несколько вариантов: 1) сначала загрузить список продуктов, затем выполнить цикл и загрузить необходимые данные для каждой строки продукта. 2) сначала создайте большое объединение для всех таблиц, а затем переберите (возможно, массивный) декартово произведение. Второй может быть довольно уродливым для разбора. Например, если у вас есть продукт A и продукт B, а продукт A имеет установку 1, установку 2, установку 3, а продукт B имеет установку 1 и установку 2, то результат будет Продукт A Установить 1 Продукт A Установить 2 Продукт A Установка 3 Продукт B Установка 1 Продукт B Установка 2

Теперь добавьте свои изображения и категории в объединение, и оно может стать огромным.

Я не уверен, каковы размеры ваших таблиц, но возвращение 45 строк не должно занять много времени. Очевидная вещь, которую нужно гарантировать (и вы, вероятно, уже сделали это), заключается в том, что product_id индексируется во всех таблицах, а также в таблицах brands_products и других. В противном случае вы выполните сканирование таблицы.

Следующий вопрос - как вы отображаете свои данные на экране. Итак, вы получаете все продукты. Вам нужно загружать категории, изображения, установки, когда вы получаете список продуктов? Если вы просто выводите список продуктов на экран, вы можете подождать загрузки этих данных, пока пользователь не выберет продукты, которые они просматривают.

Кстати, любая причина, по которой вы конвертируете массив в объект

$r[] = (object)$data;

Кроме того, во второй функции вы можете просто добавить

$data = array();

перед foreach вместо

// Make sure data exists
if(!isset($data))
{
    $data = array();
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...