Optimization



UpdateCase gives you the ability to setup a optimization engine to hunt down where the slow downs exist in your application. 
-> Then systematically you can work through and speed up these functions
-> You will then have a efficient application
-> This keeps results in a database so you can later review how your system runs even when you are not testing

# 1 > Usage

To use the optimization place a few calls which will idenity how much time elapses between. 
-> This will allow you to narrow down where there are slow downs in your code

$this->optimizationAddNote('Before find function');

# 2 > AppController

Place these 3 functions in your AppController

    private function optimizationStart() {
$this->Session->write('optimization_time_start', microtime(true));
$this->Session->write('optimization_notes', ''); //first empty it

//new method
$_SESSION['optimization_time_start'] = microtime(true);
$_SESSION['optimization_notes'] = '';
$file = APP.'tmp'.DS.'logs'.DS.'optimization';

$this->writeToLog('optimization', 'Starting');
}

public function optimizationAddNote($newNote) {

if (!isset($optObj)) {
$optObj = ClassRegistry::init('Optimization', 'Model');
}

$optObj->addNote($newNote);

}

private function setPageNameToView() {

$page = '';
$div = '_';

if (isset($this->params->params['prefix'])) {
$page .= $this->params->params['prefix'].$div;
}
if (isset($this->params->params['controller'])) {
$page .= $this->params->params['controller'].$div;
}
if (isset($this->params->params['action'])) {
$page .= $this->params->params['action'].$div;
}

if (isset($this->params->params['named'])) {
$page .= implode('_', $this->params->params['named']).$div;
}
if (isset($this->params->params['pass'])) {
$page .= implode('_', $this->params->params['pass']).$div;
}

$this->set('currentPage',
$page
);
}


function beforeFilter() {

$this->optimizationStart();
$this->optimizationAddNote('Start'); //place these to test specific locations
........
}

# 3 > Place at END of LAYOUT

At the end of your layout (app/View/Layout/default.ctp) place this code
-> This is the last place to run so it is our end point

<?php
//let's log our api calls
$optimizationObj = ClassRegistry::init('Optimization', 'Model');
$res = $optimizationObj->addToLog(
$user_id,
$customer_id,
$currentPage,
(microtime(true) - $_SESSION['optimization_time_start']),
$_SESSION['optimization_notes']
);
?>

# 4 > Create DB

Create the 'optimizations' database using the following SQL

CREATE TABLE IF NOT EXISTS `test_updateCase`.`optimization` ( `id` INT NOT NULL AUTO_INCREMENT , `user_id` INT NOT NULL , `customer_id` INT NOT NULL , `page` VARCHAR(1000) NOT NULL , `datetime` DATETIME NOT NULL , `loadtime` DECIMAL(10,5) NOT NULL , `info` TEXT NOT NULL, `created` DATETIME NOT NULL , `modified` DATETIME NOT NULL,  PRIMARY KEY (`id`)) ENGINE = InnoDB;

# 5 > Add function
Create this function in the Optimization (model) app/Models/Optimization.php

function addToLog($user_id, $customer_id, $pageName, $loadTime, $info) {
$model = 'Optimization';
$this->data[$model]['id'] = NULL;
$this->data[$model]['user_id'] = $user_id;
$this->data[$model]['datetime'] = date('Y-m-d H:i:s');
$this->data[$model]['customer_id'] = $customer_id;
$this->data[$model]['page'] = $pageName;
$this->data[$model]['loadtime'] = $loadTime;
$this->data[$model]['info'] = $info;


if ($this->save($this->data)) {
return true;
} else {
die ('cannot save optimization');
}
}




function addNote($newNote, $limitToEvery = false)
{

if ($limitToEvery) {
$this->count++;

if ($this->count > $limitToEvery) {
$this->count = 0;
//we hit our max, so we will now take some notes
} else {
//$newNote = 'skipping';
//return false; //skip until we hit our max
}
}

//$note = $this->Session->read('optimization_notes');
$note = $_SESSION['optimization_notes'];
if (!empty($note)) {
$note .= "<br/>\n";
}
//$note .= number_format(microtime(true) - $this->Session->read('optimization_time_start'), 3).': ';
$note .= number_format(microtime(true) - $_SESSION['optimization_time_start'], 3) . ': ';
$note .= $newNote;
//$this->Session->write('optimization_notes', $note); //first empty it
$_SESSION['optimization_notes'] = $note; //first empty it

$this->writeToLog('optimization', $note);

}

 


# 6 > Database changes

First logon to MYSQL and run the following commands

MAMP

/Applications/MAMP/Library/bin/mysql --host=localhost -ulocal -ppassword

LINUX

mysql --host=localhost -ulocal -ppassword

While your slow code is running - run this command a few times to see which db connections are slow

show full processlist \G;

Verify your indexes between database tables

SHOW INDEXES FROM tables;

If you want to create NEW indexes

ALTER TABLE `revisions` ADD INDEX( `phase_id`);

OR Create composite indexes
-> Look at all the conditions and where you have multiple calls you need to create composits for this
-> EG: if you have the following conditions

$conditions = array('AND' => array(
array('Revision.phase_id' => $phase_id),
array('Revision.element_id' => $element_id)
));

You need to create the index in MYSQL:

ALTER TABLE `revisions` ADD INDEX( `phase_id`, `element_id`);

 

If you need to remove an index

DROP INDEX `nameOfIndex` ON `tableName`;

done


# 7 > Cakephp DEBUG

Install CakePHP debug mode
-> View SQL log
-> This will display how long each DB call has took

Modify the indexes per the result to speed up the system.


Other Instructions

Below are many other instructions that show you how to use your UpdateCase application