diff --git a/app/Config/Schema/db_acl.php b/app/Config/Schema/db_acl.php index 7ba826b04..290a066cd 100644 --- a/app/Config/Schema/db_acl.php +++ b/app/Config/Schema/db_acl.php @@ -56,7 +56,11 @@ class DbAclSchema extends CakeSchema { 'alias' => array('type' => 'string', 'null' => true), 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'idx_acos_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0), + 'idx_acos_alias' => array('column' => 'alias', 'unique' => 0) + ) ); /** @@ -70,7 +74,11 @@ class DbAclSchema extends CakeSchema { 'alias' => array('type' => 'string', 'null' => true), 'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), 'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)) + 'indexes' => array( + 'PRIMARY' => array('column' => 'id','unique' => 1), + 'idx_aros_lft_rght' => array('column' => array('lft', 'rght'), 'unique' => 0), + 'idx_aros_alias' => array('column' => 'alias', 'unique' => 0) + ) ); /** @@ -85,7 +93,11 @@ class DbAclSchema extends CakeSchema { '_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), '_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), '_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2), - 'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1)) + 'indexes' => array( + 'PRIMARY' => array('column' => 'id', 'unique' => 1), + 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1), + 'idx_aco_id' => array('column' => 'aco_id', 'unique' => 0) + ) ); } diff --git a/app/Config/Schema/db_acl.sql b/app/Config/Schema/db_acl.sql index 274780e26..ece2ee125 100644 --- a/app/Config/Schema/db_acl.sql +++ b/app/Config/Schema/db_acl.sql @@ -38,4 +38,15 @@ CREATE TABLE aros ( lft INTEGER(10) DEFAULT NULL, rght INTEGER(10) DEFAULT NULL, PRIMARY KEY (id) -); \ No newline at end of file +); + +/* this indexes will improve acl perfomance */ +CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rhgt`); + +CREATE INDEX idx_acos_alias ON `acos` (`alias`); + +CREATE INDEX idx_aros_lft_rght ON `aros` (`lft`, `rhgt`); + +CREATE INDEX idx_aros_alias ON `aros` (`alias`); + +CREATE INDEX idx_aco_id ON `aros_acos` (`aco_id`); \ No newline at end of file diff --git a/lib/Cake/Model/AclNode.php b/lib/Cake/Model/AclNode.php index a565eb7a1..63c29f04d 100644 --- a/lib/Cake/Model/AclNode.php +++ b/lib/Cake/Model/AclNode.php @@ -89,6 +89,8 @@ class AclNode extends Model { )), 'order' => $db->name("{$type}.lft") . ' DESC' ); + + $conditionsAfterJoin = array(); foreach ($path as $i => $alias) { $j = $i - 1; @@ -98,18 +100,23 @@ class AclNode extends Model { 'alias' => "{$type}{$i}", 'type' => 'INNER', 'conditions' => array( - $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft"), - $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght"), - $db->name("{$type}{$i}.alias") . ' = ' . $db->value($alias, 'string'), - $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id") + $db->name("{$type}{$i}.alias") . ' = ' . $db->value($alias, 'string') ) ); + + // it will be better if this conditions will performs after join operation + $conditionsAfterJoin[] = $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id"); + $conditionsAfterJoin[] = $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght"); + $conditionsAfterJoin[] = $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft"); $queryData['conditions'] = array('or' => array( $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght"), $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}{$i}.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}{$i}.rght")) ); } + + $queryData['conditions'] = array_merge($queryData['conditions'], $conditionsAfterJoin); + $result = $db->read($this, $queryData, -1); $path = array_values($path);