+++ Introduction

Indexes are used to find rows with specific column values quickly. Without an index, the database must begin with the first row and then read through the entire table to find the relevant rows. 

The larger the table, the more this consumes time. If the table has an index for the columns in question, the database can quickly determine the position to seek to in the middle of the data file without having to look at all the data. If a table has 1,000 rows, this is at least 100 times faster than reading rows one-by-one.

Indexes come with a cost as they slow down the inserts and updates. However, in general you should **always** use indexes for the fields that are used in SQL where conditions.


+++ Adding indexes

You can add indexes by simple calling {{Doctrine_Record::index('indexName', $definition)}} where {{$definition}} is the definition array.

An example of adding a simple index to field called {{name}}:

<code type="php">
class IndexTest extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->hasColumn('name', 'string');

        $this->index('myindex', array('fields' => 'name');
    }
}
</code>

An example of adding a multi-column index to field called {{name}}:

<code type="php">
class MultiColumnIndexTest extends Doctrine_Record
{
    public function setTableDefinition() 
    {
        $this->hasColumn('name', 'string');
        $this->hasColumn('code', 'string');

        $this->index('myindex', array('fields' => array('name', 'code')));
    }
}
</code>

An example of adding a multiple indexes on same table:

<code type="php">
class MultipleIndexTest extends Doctrine_Record
{
    public function setTableDefinition() 
    {
        $this->hasColumn('name', 'string');
        $this->hasColumn('code', 'string');
        $this->hasColumn('age', 'integer');

        $this->index('myindex', array('fields' => array('name', 'code')));
        $this->index('ageindex', array('fields' => array('age'));
    }
}
</code>


+++ Index options

Doctrine offers many index options, some of them being db-specific. Here is a full list of available options:

<code>
sorting     => string('ASC' / 'DESC')      
        what kind of sorting does the index use (ascending / descending)

length      => integer
        index length (only some drivers support this)

primary     => boolean(true / false)        
        whether or not the index is primary index

type        => string('unique',         -- supported by most drivers
                      'fulltext',       -- only availible on Mysql driver
                      'gist',           -- only availible on Pgsql driver
                      'gin')            -- only availible on Pgsql driver
</code>

<code type="php">
class MultipleIndexTest extends Doctrine_Record
{
    public function setTableDefinition() 
    {
        $this->hasColumn('name', 'string');
        $this->hasColumn('code', 'string');
        $this->hasColumn('age', 'integer');

        $this->index('myindex', array(
                      'fields' => array(
                                  'name' =>
                                  array('sorting' => 'ASC',
                                        'length'  => 10),
                                  'code'),
                      'type' => 'unique',
                      ));
    }
}
</code>


+++ Special indexes

Doctrine supports many special indexes. These include Mysql FULLTEXT and Pgsql GiST indexes. In the following example we define a Mysql FULLTEXT index for the field 'content'.

<code type="php">
class Article 
{
    public function setTableDefinition() 
    {
    	$this->hasColumn('name', 'string');
        $this->hasColumn('content', 'string');

        $this->index('content', array('fields' => 'content',
                                      'type'   => 'fulltext'));
    }
}
</code>
