I found documents explaining that Oracle uses these for performance tuning etc, but didn't quite understand what does it actually do.
Can someone explain it to me in simple words with very basic example?
Most enterprise databases, Oracle included, use a cost-based optimizer to determine the appropriate query plan for a given SQL statement. This means that the optimizer uses information about the data to determine how to execute a query rather than relying on rules (this is what the older rule-based optimizer did).
For example, imagine a table for a simple bug-tracking application
CREATE TABLE issues (
issue_id number primary key,
issue_text clob,
issue_status varchar2(10)
);
CREATE INDEX idx_issue_status
ON issues( issue_status );
If I'm a large company, I might have 1 million rows in this table. Of those, 100 have an issue_status
of ACTIVE, 10,000 have an issue_status
of QUEUED, and 989,900 have a status of COMPLETE. If I want to run a query against the table to find my active issues
SELECT *
FROM issues
WHERE issue_status = 'ACTIVE'
the optimizer has a choice. It can either use the index on issue_status
and then do a single-row lookup in the table for each row in the index that matches or it can do a table scan on the issues
table. Which plan is more efficient will depend on the data that is in the table. If Oracle expects the query to return a small fraction of the data in the table, using the index would be more efficient. If Oracle expects the query to return a substantial fraction of the data in the table, a table scan would be more efficient.
DBMS_STATS.GATHER_TABLE_STATS
is what gathers the statistics that allow Oracle to make this determination. It tells Oracle that there are roughly 1 million rows in the table, that there are 3 distinct values for the issue_status
column, and that the data is unevenly distributed. So Oracle knows to use an index for the query to find all the active issues. But it also knows that when you turn around and try to look for all the closed issues
SELECT *
FROM issues
WHERE issue_status = 'CLOSED'
that it will be more efficient to do a table scan.
Gathering statistics allows the query plans to change over time as the data volumes and data distributions change. When you first install the issue tracker, you'll have very few COMPLETED issues and more ACTIVE and QUEUED issues. Over time, the number of COMPLETED issues rises much more quickly. As you get more rows in the table and the relative fraction of those rows that are in the various statuses change, the query plans will change so that, in the ideal world, you always get the most efficient plan possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With