В ответ на: это необходимые издержки объектно-ориентированного кода с объектно-ориентированными универсальными прослойками методов
... как-то далеко не уверен. ООП - в своей основе - это табличное программирование, которое всегда было самым компактным и самым быстрым... в мое время. Оно канечна, "всё течёт, всё изменяется", но не до такой же степени!
В ответ на: нужно тюнить БД и рефакторить не пэхопэ, а схему данных
Этим тоже занимаюсь.
Так например вот это:
$select->from(array('cl' => $this->_name), array(
'id' => 'cl.id',
'name' => 'cl.name',
'created_at' => 'DATE_FORMAT(cl.created_at, \'%d.%m.%Y\')',
'companies_count' => 'COUNT(DISTINCT ccd.id)',
'begin_date' => 'ccf.begin_date',
'end_date' => 'ccf.end_date',
'not_distributed' => 'COUNT(DISTINCT ccd.id) - COUNT(DISTINCT ccp.id)',
'creator_name' => "CONCAT(IFNULL(p.lname, ''), ' ', IFNULL(p.fname, ''))",
'allow_edit' => 'NOT ISNULL(ccf.begin_date)',
'isowner' => 'IF(cl.created_by = ccf.owner, true, false)',
'ccf_id' => 'ccf.id'
))
->joinLeft(array('ccf' => 'clists_m_company_function'), 'ccf.list_id = cl.id', array())
->joinLeft(array('ccd' => 'clists_company_department'), 'ccd.clists_m_company_function_id = ccf.id', array())
->joinLeft(array('dw' => 'm_division_worker'), 'dw.m_company_function_id = ccf.m_company_function_id', array())
->joinLeft(array('cp' => 'm_company_people'), 'dw.m_company_people_id = cp.id', array())
->joinLeft(array('u' => 'usr_users'), 'u.`data_type` = \'m_company_people\' AND u.data_id = cp.id', array())
->joinLeft(array('u2' => 'usr_users'), 'u2.id = cl.created_by', array())
->joinLeft(array('cp2' => 'm_company_people'), 'u2.data_id = cp2.id AND u2.data_type = \'m_company_people\'', array())
->joinLeft(array('p' => 'm_people'), 'p.id = cp2.m_people_id', array())
->joinLeft(array('ccp' => 'clists_m_company_people'), 'ccp.clists_m_company_function_id = ccf.id', array())
->where('u.id = ?', $user);
выбиралось за время более 20-и минут, в зависимости от нагрузки на мускуль. Да ещё и неправильно делаются подсчеты. Так для списка из 2405 фирм, в результате показывается companies_count = 10848... и это при том, что в базовой таблице всего ... 12 списков.
Убрал ВСЕ вспомогательные таблицы, добавив всего 4 поля в таблицу фирм списка 'clists_m_company' (вместо clists_m_company_function и clists_m_company_departments): `department_id`, `manager_id`, `for_deps_at` и `for_mans_at`, опираясь на то, что фирма из списка, может быть назначена единовременно только одному менеджеру и дополнительное условие что менеджер может быть назначен только после назначения отделу... весь запрос превратился в простой подсчет количества записей с заданным и пустым manager_id и department_id с группировкой по заданному списку... время отклика всей страницы... менее 2 сек.
Итого, от системы списков осталась таблица имен списков и таблица фирм этих списков с текущим указанием какая - кому назначена... всё.