DEV Community

Pranav Bakare
Pranav Bakare

Posted on

Function-Based Index in SQL

Function-Based Index in Oracle SQL

Definition:

A Function-Based Index (FBI) in Oracle SQL is an index that stores the results of a function or expression applied to one or more columns of a table. Unlike regular indexes, which are directly based on the column values, a function-based index allows you to index a transformation of the data (e.g., UPPER(column_name), ROUND(column_name), or any user-defined function). This can help optimize queries that use functions or expressions in their WHERE clauses, improving query performance.

Syntax:

CREATE INDEX index_name ON table_name (function_or_expression);

index_name: The name of the function-based index.

table_name: The name of the table on which the index is created.

function_or_expression: The function or expression that will be indexed.

Why Use Function-Based Indexes:

Function-based indexes are required because:

  1. Function Calls in WHERE Clauses Are Slow: When a query uses a function or expression on a column in the WHERE clause, Oracle cannot use a regular index on that column. It has to perform a full table scan, which can be slow for large datasets.

  2. Case-Insensitive Searches: Regular indexes are case-sensitive, and searches like WHERE UPPER(name) = 'JOHN' cannot use a normal index on name. A function-based index on UPPER(name) solves this problem.

  3. Computed Values: If you need to frequently query derived values (e.g., salary * 12), a function-based index can speed up those queries.

By creating a function-based index, you can enable Oracle to use the index, even when the query applies a function to the column, thus avoiding a full table scan and improving performance.

Example:

Scenario:

Suppose you have an employees table and you frequently perform case-insensitive searches on the name column:

CREATE TABLE employees (
id NUMBER,
name VARCHAR2(100),
salary NUMBER
);

You want to search for names without considering case sensitivity:

SELECT * FROM employees WHERE UPPER(name) = 'JOHN DOE';

If you have a regular index on name, Oracle will not use it because the query applies the UPPER function. It will perform a full table scan instead.

Step 1: Create a Function-Based Index

CREATE INDEX idx_upper_name ON employees (UPPER(name));

This index stores the result of UPPER(name) for each row in the table.

Now, Oracle can use the index when the query applies UPPER(name) in the WHERE clause.

Step 2: Optimized Query Using the Index

SELECT * FROM employees WHERE UPPER(name) = 'JOHN DOE';

With the function-based index idx_upper_name in place, Oracle can quickly locate matching rows using the index, rather than scanning the entire table.

How Function-Based Indexes Optimize Queries:

  1. Avoid Full Table Scans: Without a function-based index, queries that use functions (like UPPER, ROUND, or user-defined functions) cannot use regular indexes, leading to full table scans. Function-based indexes allow Oracle to index the result of the function, enabling faster lookups.

  2. Reduced I/O: Since the index stores pre-computed results, Oracle can quickly locate the matching rows, reducing the amount of I/O operations needed to find data.

  3. Pre-computation: The function or expression is calculated once when the index is created (and updated during DML operations), saving processing time during query execution.

  4. Faster Query Performance: By allowing the use of indexes for queries that apply functions, function-based indexes can significantly speed up query performance, especially for large datasets.

Example with a Deterministic Function:

If you have a deterministic function that converts dates to quarters, you can use a function-based index to speed up queries based on that logic.

  1. Create the Function:

CREATE OR REPLACE FUNCTION get_quarter(sale_date DATE)
RETURN NUMBER DETERMINISTIC IS
BEGIN
RETURN TO_NUMBER(TO_CHAR(sale_date, 'Q'));
END;
/

  1. Create a Function-Based Index:

CREATE INDEX idx_sales_quarter ON sales (get_quarter(sale_date));

  1. Optimized Query:

SELECT * FROM sales WHERE get_quarter(sale_date) = 2;

Oracle will use the idx_sales_quarter index, resulting in faster query execution.

Summary:

A function-based index enhances query performance by allowing Oracle to use an index even when the query involves functions or expressions on columns. This avoids full table scans, reduces processing time, and improves efficiency for searches, computations, and case-insensitive queries. By pre-computing and storing the function results, Oracle can quickly return the data, making it a valuable tool for query optimization.

Top comments (0)