2009-08-14 4 views
2

Я создаю веб-сайт с использованием фреймворков, mysql и zend framework. Когда я пытаюсь запустить любой sql-запрос, генерация страниц начинается примерно на 0,5 секунды. Это слишком высоко. Если я превращу sql, создание страницы - 0.001. Количество запросов, которые я запускаю, на самом деле не влияет на время создания страницы (проверено 1-10 запросов). Остается на 0,5 секунды Я не могу понять, что я делаю неправильно.Zend Framework и Mysql - очень медленно

подключиться к SQL в загрузчике:

protected function _initDatabase() 
{ 
    try 
    { 
     $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV); 
     $db = Zend_Db::factory($config -> database); 
     Zend_DB_Table_Abstract::setDefaultAdapter($db); 
    } 
    catch (Zend_Db_Exception $e) 
    { 

    } 
} 

Тогда у меня есть простая модель

class StandardAccessory extends Zend_DB_Table_Abstract 
{ 
    /** 
    * The default table name 
    */ 
    protected $_name = 'standard_accessory'; 

    protected $_primary = 'model'; 

    protected $_sequence = false; 
} 

И, наконец, в мой контроллер индекса, я просто запустить метод найти.

require_once APPLICATION_PATH . '/models/StandardAccessory.php'; 
    $sa = new StandardAccessory(); 
    $stndacc = $sa->find('abc'); 

Все это занимает ~ 0,5 секунды, что слишком долго. Какие-либо предложения?

Спасибо!

ответ

5

Советы:

  • Cache the table metadata. По умолчанию Zend_Db_Table пытается обнаружить метаданные о таблице каждый раз, когда создается экземпляр вашего объекта таблицы. Используйте кеш, чтобы уменьшить количество попыток сделать это. Или же жестко запрограммируйте его в своем классе Table (примечание: db-таблицы не являются моделями).

  • Использовать EXPLAIN для анализа плана оптимизации MySQL. Использует ли он эффективный индекс?

    mysql> EXPLAIN SELECT * FROM standard_accessory WHERE model = 'abc'; 
    
  • Использование BENCHMARK() для измерения скорости запроса, а не с помощью PHP. Подзапрос должен возвращать один столбец, поэтому обязательно верните неиндексированный столбец, чтобы запрос коснулся данных вместо того, чтобы просто возвращать запись индекса.

    mysql> SELECT BENCHMARK(1000, 
        (SELECT nonindexed_column FROM standard_accessory WHERE model = 'abc')); 
    
  • Обратите внимание, что Zend_Db_Adapter отложенной загружает его соединение с базой данных, когда вы сделаете первый запрос. Поэтому, если есть некоторая медленность при подключении к серверу MySQL, это произойдет, когда вы создаете экземпляр объекта Table (когда он запрашивает метаданные). По какой-то причине это может занять много времени? DNS lookups, возможно?

+0

И запрос для BENCHMARK должен возвращать 1 строку, иначе mysql будет жаловаться: ERROR 1242 (21000): Подзапрос возвращает более 1 строки. –

+0

@Leonel Martins: Правильно, я полагаю, поскольку OP использует 'find()', что он ограничивает первичный ключ таблицы. Поэтому должно быть гарантировано вернуть одну строку (или нулевые строки, если «abc» не найден). –

+0

Первая ссылка на кэширование метаданных теперь недействительна, я предполагаю, что она такова: https://framework.zend.com/manual/1.10/en/zend.db.table.html#zend.db.table. metadata.caching –

2

Самый простой способ отладить это - это профилировать ваши запросы sql. вы можете использовать Firephp (плагин для firebug), см. http://framework.zend.com/manual/en/zend.db.profiler.html#zend.db.profiler.profilers.firebug

Другой способ ускорить работу немного, чтобы кешировать метаданные ваших таблиц. см: http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.metadata.caching

0

Наряду с вышеуказанными предложениями я сделал очень ненаучный тест и обнаружили, что адаптер PDO был быстрее меня в моем приложении (я знаю MySQLi должен быть быстрее, но, возможно, это ZF абстракция). Я показываю результаты here (показано только время)