@entermix

Как правильно выполнить выборку?

Допустим нам нужно сформировать массив для последующего вывода в таблицу статистики сайта:

$data = [
    // ...
    'sms' => [
                'new' => [
                    'today' => ORM::factory('Sms')
                        ->where('created', '>', mktime(0, 0, 0, date('m'), date('d'), date('Y')))
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'new')->find()
                        )
                        ->count_all(),
                    'yesterday' => ORM::factory('Sms')
                        ->where('created', '<', mktime(0, 0, 0, date('m'), date('d'), date('Y')))
                        ->and_where('created', '>', mktime(0, 0, 0, date('m', time() - Date::DAY), date('d', time() - Date::DAY), date('Y', time() - Date::DAY)))
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'new')->find()
                        )
                        ->count_all(),
                    'hour' => ORM::factory('Sms')
                        ->where('created', '>', time() - Date::HOUR)
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'new')->find()
                        )
                        ->count_all(),
                    'day' => ORM::factory('Sms')
                        ->where('created', '>', time() - Date::DAY)
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'new')->find()
                        )
                        ->count_all(),
                        
                        // ...
                        
                    'all' => ORM::factory('Sms')
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'new')->find()
                        )
                        ->count_all(),
                ],
                'sent' => [
                        // ...

                    'all' => ORM::factory('Sms')
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'sent')->find()
                        )
                        ->count_all(),
                ],
                'not_sent' => [
                        //...
                        
                    'all' => ORM::factory('Sms')
                        ->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'not_sent')->find()
                        )
                        ->count_all(),
                ],
            ],
        // ...
    ];


Как видим, для поиска применяется объект, который достается с БД, а следовательно это + 1 запрос на каждую выборку:

->and_where('status_id', '=', ORM::factory('Sms_Status')
                                ->where('name', '=', 'not_sent')->find()


Таких параметров в $data будет много (users, email, sms, etc..) в данный момент получается 500+ запросов, использоваться все будет для админки, т.е. никакой нагруженности, собственно как более правильно организовать все?

Сделать такие запрос для and_where перед формированием массива (чтобы он выполнялся всего 1 раз), или забить на все просто включив кеширование MySQL?
  • Вопрос задан
  • 258 просмотров
Пригласить эксперта
Ответы на вопрос 1
Melkij
@Melkij
PostgreSQL DBA
select st.name, count(0) from Sms join Sms_status st on status_id = st.id where st.name in ('sent','not_sent', 'new') group by status_id

Аналогично и первая толпа запросов сворачивается в один простой SQL.

А с учётом сущности данных - имеет смысл их перенести в отдельную таблицу аггрегации и не пересчитывать в рантайме весь массив.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы