Wednesday, August 16, 2006

The case for function based indexes - part two

Some time ago I wrote about function based indexes, showing a PostgreSQL based case, right now I'll show a Firebird based example, due to the fact that Firebird 2.0 supports Expression Indexes, which are my good old function based indexes.
This example will be based on the sample database which ships with Firebird, named EMPLOYEE.FDB.
As the old example was based on extracting a substring from a code, I'll show you a similar one, this will also highlight syntax differencies between Firebird and PostgreSQL

  1. CREATE INDEX idx3 ON employee
  2. computed BY (SUBSTRING(dept_no FROM 1 FOR 2));

Now you see that I created an index named idx3 on table employee made of the first two chars of column dept_no (substring starts from position 1 and goes on for the number of chars specified).
After committing changes (with Firebird you can rollback data definition statements!) you can check if the index is picked up with a query like:

  1. SELECT SUBSTRING(dept_no FROM 1 FOR 2), first_name
  2. FROM employee
  3. ORDER BY SUBSTRING(dept_no FROM 1 FOR 2);

It's plan is:

PLAN (EMPLOYEE ORDER IDX3)

which clearly shows that the index is picked up!
Note that a query like:

  1. SELECT SUBSTRING(dept_no FROM 1 FOR 2), first_name
  2. FROM employee
  3. ORDER BY 2;

Which means "order by first_name" results in a plan like:

PLAN SORT ((EMPLOYEE NATURAL))

The index is correctly ignored.
And a query like:

  1. SELECT SUBSTRING(dept_no FROM 1 FOR 2), first_name
  2. FROM employee
  3. ORDER BY dept_no;

Results in yet another plan, in which an index built on the whole dept_no column is chosen over the "expression index":

PLAN (EMPLOYEE ORDER RDB$FOREIGN8)

A quick glance to all the indexes existing on this table can be taken from this query:

  1. SELECT
  2. *
  3. FROM rdb$indices
  4. WHERE rdb$relation_name = 'EMPLOYEE';

No comments: