Saturday, 13 July 2013

Oracle Database Concepts II

Hi Guys,

This is part 2 of Oracle database basics.For part 1 refer below link 

Link for Oracle Database basics Part 1


So consider there is a big query .First time you run it .It takes 30 seconds second time it takes 7 seconds.Now what is the query time (7 or 30) and why this happens.

Answer - First time it reads from physical memory (actual db) ,Next time it reads from cache.This is very important to understand for sql tuning (physical reads and Consistent gets) .

What is database Instance.

A database instance is a set of memory structures that manage database files. A database is a set of physical files on disk created by the CREATE DATABASE statement. The instance manages its associated data and serves the users of the database.

Every running Oracle database is associated with at least one Oracle database instance. Because an instance exists in memory and a database exists on disk, an instance can exist without a database and a database can exist without an instance.(SGA Exists in your RAM).So more the RAM for your server its faster


When an instance is started, Oracle Database allocates a memory area called the system global area (SGA) and starts one or more background processes. The SGA serves various purposes, including the following:

•Maintaining internal data structures that are accessed by many processes and threads concurrently

•Caching data blocks read from disk

•Buffering redo data before writing it to the online redo log files

•Storing SQL execution plans

The SGA is shared by the Oracle processes, which include server processes and background processes, running on a single computer. The way in which Oracle processes are associated with the SGA varies according to operating system.

A database instance includes background processes. Server processes, and the process memory allocated in these processes, also exist in the instance. The instance continues to function when server processes terminate.


The most important SGA components are the following:
 

  1. Database Buffer Cache 
  2. Redo Log Buffer
  3. Shared Pool
  4. Large Pool
  5. Java Pool
  6. Streams Pool
  7. Fixed SGA




SGA (contains buffer cache)

The System Global Area (SGA) is a group of shared memory areas that are dedicated to an Oracle “instance” (an instance is your database programs and RAM).

Main Areas of SGA

1) The buffer cache (db_cache_size)
2)The shared pool (shared_pool_size)
3)The redo log buffer (log_buffer)

Main thing to understand is 


The Buffer Cache (also called the database buffer cache) is where Oracle stores data blocks.  With a few exceptions, any data coming in or going out of the database will pass through the buffer cache.

When Oracle receives a request to retrieve data, it will first check the internal memory structures to see if the data is already in the buffer. This practice allows to server to avoid unnecessary I/O

The database buffer cache holds copies of the data blocks read from the data files. The term data block is used to describe a block containing table data, index data, clustered data, and so on. Basically it is a block that contains data

An Oracle block is different from a disk block.  An Oracle block is a logical construct -- a creation of Oracle

Some more point on Buffer cache(For those looking for more detail)

The total space in the Database Buffer Cache is sub-divided by Oracle into units of storage called “blocks”. Blocks are the smallest unit of storage in Oracle and you control the data file blocksize when you allocate your database files.

An Oracle block is different from a disk block.  An Oracle block is a logical construct -- a creation of Oracle, rather than the internal block size of the operating system. In other words, you provide Oracle with a big whiteboard, and Oracle takes pens and draws a bunch of boxes on the board that are all the same size. The whiteboard is the memory, and the boxes that Oracle creates are individual blocks in the memory

Consistent Gets

A Consistent Get is where oracle returns a block from the block buffer cache but has to take into account checking to make sure it is the block current at the time the query started.


Oracle fetches pretty much all of its data that way. All your data in your database, the stuff you create, the records about customers or orders or samples or accounts, Oracle will ensure that what you see is what was committed at the very point in time your query started. It is a key part to why Oracle as a multi-user relational database works so well.
Most of the time, of course, the data has not changed since your query started or been replaced by an uncommitted update. It is simply taken from the block buffer cache and shown to you.

A Consistent Get is a normal get of normal data. You will see extra gets if Oracle has to construct the original record form the rollback data. You will probably only see this rarely, unless you fake it up.

Consistent Gets – a normal reading of a block from the buffer cache. A check will be made if the data needs reconstructing from rollback info to give you a consistent view but most of the time it won’t.
DB Block Gets – Internal processing. Don’t worry about them unless you are interested in Oracle Internals and have a lot of time to spend on it.
Physical Reads – Where Oracle has to get a block from the IO subsystem

Nicely explained by below blog 

http://mwidlake.wordpress.com/2009/06/02/what-are-consistent-gets/

My full article on Consistent Gets 

http://cognossimplified.blogspot.in/2013/09/using-consistent-gets-to-tune-sql.html 

What is latching 

Along with keeping physical I/O to minimum we also need to keep consistent gets to minimum as consistent gets involve latching. A latch is a lock.
Locks are serialization devices.Consider 2 users were accessing a table ( from cache ) when first user is reading a latch is set so that it reads only current data and 2 person has to wait till this latch is free

Serialization devices inhibit scalability, the more you use them, the less concurrency you get.

Though common idea is to keep physical read to minimum we also want to keep consistent gets minimum due to various reason like it might create latches issue and high cpu utilizatoin and for that consistent get to happen . physical i/o must have occured some time.

Consider you had a bigger cache that the physical i/o will be reduced but does that solve the probelem .NO


http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6643159615303

what is recursive calls 

Sometimes, to execute a SQL statement issued by a user, the Oracle Server must issue additional statements. Such statements are called recursive calls or recursive SQL statements. For example, if you insert a row into a table that does not have enough space to hold that row, the Oracle Server makes recursive calls to allocate the space dynamically if dictionary managed tablespaces are being used. Recursive calls are also generated:

When data dictionary information is not available in the data dictionary cache and must be retrieved from disk

  • In the firing of database triggers
  • In the execution of DDL statements
  • In the execution of SQL statements within stored procedures, functions, packages and anonymous PL/SQL blocks
  • In the enforcement of referential integrity constraints


The value of this statistic will be zero if there have not been any write or update transactions committed or rolled back during the last sample period. If the bulk of the activity to the database is read only, the corresponding "per second" metric of the same name will be a better indicator of current performance.



Dynamic sampling --- allows CBO to estimate number of rows for tables that are not analysed .Which helps it to come up with better estimation plan.

The number of rows show in dynamic sampling are not actual rows but a estimate from dynamic sampling

What is Clustering factor 

Oracle has something called cluster tables ( data from two tables having common column) saved on same block and index on such cluster table is called clustered index.

Now Clustering factor is something different 


the clustering_factor column in the user_indexes view is a measure of how organized the data is compared to the indexed column, is there any way i can imporve clustering factor of a index. or how to improve it

This defines how ordered the rows are in the index.  If CLUSTERING_FACTOR approaches the
number of blocks in the table, the rows are ordered.  If it approaches the number of rows in the table, the rows are randomly ordered.  In such a case (clustering factor near the number of rows), it is unlikely that index entries in the same leaf block will point to rows in the same data blocks.

Note that typically only 1 index per table will be heavily clustered (if any).  It would be extremely unlikely for 2 indexes to be very clustered.

If you want an index to be very clustered -- consider using index organized tables.  They force the rows into a specific physical location based on their index entry.

Otherwise, a rebuild of the table is the only way to get it clustered (but you really don't want to get into that habit for what will typically be of marginal overall improvement)

Easy way to create a dummy table with lot of Rows

create table t ( a int, b int, c char(20), d char(20), e int );

 insert into t select 1, 1, 1, 1, rownum from all_objects;

create unique index t_idx on t(a,b,c,d,e);



Disclaimer and Citations 

The content here is taken from various sources found by googling. I have given links wherever possible.For me i dont need in detail information so i have copy pasted the basic information for my use.Also taken are comments from blogs , forum. I have added lot of information according to my understanding of subjects. If anyone finds anything objectionable please leave a comment.


Friday, 12 July 2013

How to Enable Statistics IO in sql developer

Hi Guys,

This is a part of Explaination of Explain plan and Statistics IO.Meant as trouble shooting article.

Note -- The statistics shown in sql developer and Sql plus are different. Check below for sql plus statistics from autotrace. Those are the most important ones .








Its not possible to show consistent gets in sql developer using Autotrace. So you need to use Sql Plus . It gives you the Execution plan. The plan that was actually used by sql to run.  Below are commands


How to use SQL Plus

SET long 500 longchunksize 500

SET LINESIZE 1024

SET AUTOTRACE TRACEONLY;

c:\users\kapil\desktop>sql plus user/password@tnsname >outputfilename.txt@fileofsql.sql



Below is example of Statistics IO 

   Statistics
-----------------------------------------------------------
               3  user calls
               0  physical read total bytes
               0  physical write total bytes
               0  spare statistic 3
               0  commit cleanout failures: cannot pin
               0  TBS Extension: bytes extended
               0  total number of times SMON posted
               0  SMON posted for undo segment recovery
               0  SMON posted for dropping temp segment
               0  segment prealloc tasks

If you try below command in sql developer

 set statistics IO on --For sql plus only.  
 set Autotrace on --- For sql developer it will show at the end of the script the statistics and the explain plans


you will get below error 

The statistic feature requires that the user is granted select on v_$sesstat, v_$statname and v_$session.

Some more options for Autotrace

set autotrace on: Shows the execution plan as well as statistics of the statement.
set autotrace on explain: Displays the execution plan only.
set autotrace on statistics: Displays the statistics only.
set autotrace traceonly: Displays the execution plan and the statistics (as set autotrace on does), but doesn't print a query's result.
set autotrace off: Disables all autotrace

Why this Error

Sqltrace is not installed by default with oracle installation.We need to login with user with admin right and then follow below steps.

Steps

1) Login - sys as sysdba  password leave blank just press enter
2) My path of file

Path of the file.
E:\app1\ADMIN\product\11.2.0\dbhome_1\sqlplus\admin

Just write @ before E and then ; at the end and press enter.See screenshot below





3) Close sql developer and open again

4) select * from dual

Run as script you will get this




Plan hash value: 272002086

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     2 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

   Statistics
-----------------------------------------------------------
               3  user calls
               0  physical read total bytes
               0  physical write total bytes
               0  spare statistic 3
               0  commit cleanout failures: cannot pin
               0  TBS Extension: bytes extended
               0  total number of times SMON posted
               0  SMON posted for undo segment recovery
               0  SMON posted for dropping temp segment
               0  segment prealloc tasks




How to read Explain plans for Sql tuning

Hi Guys,

The main idea to improve speed of query is to get the result by going through as little physical reads ( from disk) as possible.

We do indexing , partition all things so that we can easily identify our data from millions of rows.Without having to go through each row.So the idea behind reading explain plan is identifying which part of sql is not using best way to read from db.There might be one table which is doing full scan(reading entire table) to reach at a particular row (say employee id) .Now how can we make it reach it faster , may be by not having to go through entire table and just reading one row.There are number of techniques out there.

For datawarehouse a Bitmap index may speed up {My Actual case study on DW} .OR indexes on a particular column which is forcing a full table read may speed up. So lets look what is a explain plan and What is Statistics IO.

A word of Caution for reader - Below is a article i have writen on reading Explain plans.If you have good experience ( I mean you can write and debug sql query very very easily ) then only you should read this advance stuff.Its involves a lot of detailed discussion.Not for freshers.I am not discouraging anyone but for less experienced people it wont make much sense.

Some Notes before we start

Two things we need to tune sql (Explain plan and Statistics IO) ......Since Statistics IO is not set by default.Below are steps to enable it

If you are having difficulties understanding terms discussed in this article.Please go through below link
http://cognossimplified.blogspot.in/2013/07/oracle-database-concepts.html)

Below are steps to enable Statistics IO if you dont have it enabled.(Usually DBA would have enabled this )
http://cognossimplified.blogspot.in/2013/07/how-to-enable-statistics-io-in-sql.html

Example of Explain plan and Statistics IO 

  create table t ( a int, b int, c char(20), d char(20), e int );
 
  Insert into t select 1, 1, 1, 1, rownum  from all_objects ;( it will create a dummy table with lot of records)

create index a_indx on t (a) compute statistics;

set autotrace on

select a from t where a =1

Plan hash value: 2016457929

-------------------------------------------------------------------------------
| Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        | 74275 |   942K|    44   (3)| 00:00:01 |
|*  1 |  INDEX FAST FULL SCAN| A_INDX | 74275 |   942K|    44   (3)| 00:00:01 |
-------------------------------------------------------------------------------

  Statistics
-----------------------------------------------------------
              13  user calls
               0  physical read total bytes
               0  physical write total bytes
               0  spare statistic 3
               0  commit cleanout failures: cannot pin
               0  TBS Extension: bytes extended
               0  total number of times SMON posted
               0  SMON posted for undo segment recovery
               0  SMON posted for dropping temp segment
               0  segment prealloc tasks

Very Important link gives the various terms used in explain plan in detail.

http://www.akadia.com/services/ora_interpreting_explain_plan.html

What is Index fast full scan ---They are similar to full table scans that is they read the full index and while doing so oracle will fetch the next multiple blocks in anticipation that they will be required.It makes use of flag db_file_multiblock_read . Similar to full table scan.It is used when we dont even need to touch db to get our data .See in this case the the physical read is zero.we got our result just from index scan as the column requested in select statement is a index column .

In index fast full scan index is read as a table. Normally in a index with mutliple leaf nodes we go from one node to other but in fast full scan we read all nodes. Not necessary in order and it will use multiblock i/o that is it will read from multiple blocks


select count(distinct deptno) from t
and either of EMPNO or DEPTNO is defined as "not null" -- we may very well use the INDEX
via a FAST FULL INDEX SCAN over the table (the index being a "skinny version" of the
table in this case.


Now lets change the column to one which is not indexed let see the response

select b from t where b =1

Notice that it goes for full table scan

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 74275 |   942K|   171   (1)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| T    | 74275 |   942K|   171   (1)| 00:00:03 |
--------------------------------------------------------------------------


Now lets go for condition on A .We have a index on A

select * from t where A >1

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    83 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |     1 |    83 |     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | A_INDX |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Two links which you might like

http://www.dwbiconcepts.com/database/22-database-oracle/26-oracle-query-plan-a-10-minutes-guide.html





Wednesday, 10 July 2013

A Query to understand DW concept

Hi Guys,

In month of July 2013 i was asked to improve reporting performance in datawarehouse.The reporting on DW was very slow .Report on DW were taking about 18 min to run which was unacceptable.

So i started from Oracle basics.You will see a lot of article on oracle ,Explain plan and other in July. After basics its time to understand how a query structure will be.How the actual joins should be taking place.Below is cognos GosalesDW query which has slightly Snowflaked schema same as my office environment so its good for analysis.In other article i am planning to study the explain plan of this and will try some tricks to improve plan.


SELECT (COALESCE("D2"."memberUniqueName2", "D3"."memberUniqueName2")) "memberUniqueName2",
  MIN((COALESCE("D2"."rc", "D3"."rc"))) over (partition BY (COALESCE("D2"."Product_type_key", "D3"."Product_type_key"))) "Product_type",
  (COALESCE("D2"."memberUniqueName4", "D3"."memberUniqueName4")) "memberUniqueName4",
  MIN((COALESCE("D2"."rc10", "D3"."rc8"))) over (partition BY (COALESCE("D2"."Retailer_country_key", "D3"."Retailer_country_key")), (COALESCE("D2"."Retailer_key", "D3"."Retailer_key"))) "Retailer_name",
  "D2"."memberUniqueName6" "memberUniqueName6",
  "D2"."Order_method_type" "Order_method_type",
  "D2"."Quantity" "Quantity",
  "D3"."Sales_target" "Sales_target",
  (COALESCE("D2"."Product_type_key", "D3"."Product_type_key")) "Product_type_key",
  (COALESCE("D2"."Retailer_country_key", "D3"."Retailer_country_key")) "Retailer_country_key",
  (COALESCE("D2"."Retailer_key", "D3"."Retailer_key")) "Retailer_key"
FROM
  (SELECT "T0"."C0" "memberUniqueName2",
    "T0"."C1" "memberUniqueName4",
    "T0"."C2" "memberUniqueName6",
    "T0"."C3" "Retailer_country_key",
    "T0"."C4" "Retailer_key",
    "T0"."C5" "Product_type_key",
    MIN("T0"."C6") over (partition BY "T0"."C2") "Order_method_type",
    "T0"."C7" "Quantity",
    "T0"."C8" "rc",
    "T0"."C9" "rc10"
  FROM
    (SELECT "coguda00"."PRODUCT_LINE_CODE" "C0",
      "coguda10"."REGION_CODE" "C1",
      "SLS_ORDER_METHOD_DIM"."ORDER_METHOD_KEY" "C2",
      "coguda10"."COUNTRY_KEY" "C3",
      "coguda11"."RETAILER_KEY" "C4",
      "coguda00"."PRODUCT_TYPE_KEY" "C5",
      MIN("SLS_ORDER_METHOD_DIM"."ORDER_METHOD_EN") "C6",
      SUM("SLS_SALES_FACT"."QUANTITY") "C7",
      MIN("coguda02"."PRODUCT_TYPE_EN") "C8",
      MIN("coguda11"."RETAILER_NAME") "C9"
    FROM "GOSALESDW"."SLS_PRODUCT_DIM" "coguda00",
      "GOSALESDW"."SLS_PRODUCT_LINE_LOOKUP" "coguda01",
      "GOSALESDW"."SLS_PRODUCT_TYPE_LOOKUP" "coguda02",
      "GOSALESDW"."SLS_PRODUCT_LOOKUP" "coguda03",
      "GOSALESDW"."SLS_PRODUCT_COLOR_LOOKUP" "coguda04",
      "GOSALESDW"."SLS_PRODUCT_SIZE_LOOKUP" "coguda05",
      "GOSALESDW"."SLS_PRODUCT_BRAND_LOOKUP" "coguda06",
      "GOSALESDW"."GO_REGION_DIM" "coguda10",
      "GOSALESDW"."SLS_RTL_DIM" "coguda11",
      "GOSALESDW"."SLS_ORDER_METHOD_DIM" "SLS_ORDER_METHOD_DIM",
      "GOSALESDW"."SLS_SALES_FACT" "SLS_SALES_FACT"
    WHERE "coguda00"."PRODUCT_KEY"         ="SLS_SALES_FACT"."PRODUCT_KEY"
    AND "SLS_SALES_FACT"."ORDER_METHOD_KEY"="SLS_ORDER_METHOD_DIM"."ORDER_METHOD_KEY"
    AND "coguda11"."RETAILER_SITE_KEY"     ="SLS_SALES_FACT"."RETAILER_SITE_KEY"
    AND "coguda10"."COUNTRY_CODE"          ="coguda11"."RTL_COUNTRY_CODE"
    AND "coguda00"."PRODUCT_LINE_CODE"     ="coguda01"."PRODUCT_LINE_CODE"
    AND "coguda00"."PRODUCT_NUMBER"        ="coguda03"."PRODUCT_NUMBER"
    AND "coguda00"."PRODUCT_SIZE_CODE"     ="coguda05"."PRODUCT_SIZE_CODE"
    AND "coguda00"."PRODUCT_TYPE_CODE"     ="coguda02"."PRODUCT_TYPE_CODE"
    AND "coguda00"."PRODUCT_COLOR_CODE"    ="coguda04"."PRODUCT_COLOR_CODE"
    AND "coguda06"."PRODUCT_BRAND_CODE"    ="coguda00"."PRODUCT_BRAND_CODE"
    AND "coguda03"."PRODUCT_LANGUAGE"      =N'EN'
    GROUP BY "coguda00"."PRODUCT_LINE_CODE",
      "coguda10"."REGION_CODE",
      "SLS_ORDER_METHOD_DIM"."ORDER_METHOD_KEY",
      "coguda00"."PRODUCT_TYPE_KEY",
      "coguda10"."COUNTRY_KEY",
      "coguda11"."RETAILER_KEY"
    ) "T0"
  ) "D2"
FULL OUTER JOIN
  (SELECT "T0"."C0" "memberUniqueName2",
    "T0"."C1" "memberUniqueName4",
    "T0"."C2" "Retailer_country_key",
    "T0"."C3" "Retailer_key",
    "T0"."C4" "Product_type_key",
    "T0"."C5" "Sales_target",
    "T0"."C6" "rc",
    "T0"."C7" "rc8"
  FROM
    (SELECT "Product"."Product_line_code" "C0",
      "Retailer_site"."Region_code" "C1",
      "Retailer_site"."Retailer_country_key" "C2",
      "Retailer_site"."Retailer_key" "C3",
      "Product"."Product_type_key" "C4",
      SUM("SLS_SALES_TARGET_FACT"."SALES_TARGET") "C5",
      MIN("Product"."Product_type") "C6",
      MIN("Retailer_site"."Retailer_name") "C7"
    FROM
      (SELECT "SLS_PRODUCT_DIM"."PRODUCT_LINE_CODE" "Product_line_code",
        "SLS_PRODUCT_DIM"."PRODUCT_TYPE_KEY" "Product_type_key",
        MIN("SLS_PRODUCT_TYPE_LOOKUP"."PRODUCT_TYPE_EN") "Product_type"
      FROM "GOSALESDW"."SLS_PRODUCT_DIM" "SLS_PRODUCT_DIM",
        "GOSALESDW"."SLS_PRODUCT_TYPE_LOOKUP" "SLS_PRODUCT_TYPE_LOOKUP"
      WHERE "SLS_PRODUCT_DIM"."PRODUCT_TYPE_CODE"="SLS_PRODUCT_TYPE_LOOKUP"."PRODUCT_TYPE_CODE"
      GROUP BY "SLS_PRODUCT_DIM"."PRODUCT_LINE_CODE",
        "SLS_PRODUCT_DIM"."PRODUCT_TYPE_KEY"
      ) "Product",
      (SELECT "Retailer_region_dimension"."REGION_CODE" "Region_code",
        "Retailer_region_dimension"."COUNTRY_KEY" "Retailer_country_key",
        "SLS_RETAILER_DIM"."RETAILER_KEY" "Retailer_key",
        MIN("SLS_RETAILER_DIM"."RETAILER_NAME") "Retailer_name"
      FROM "GOSALESDW"."GO_REGION_DIM" "Retailer_region_dimension",
        "GOSALESDW"."SLS_RTL_DIM" "SLS_RETAILER_DIM"
      WHERE "Retailer_region_dimension"."COUNTRY_CODE"="SLS_RETAILER_DIM"."RTL_COUNTRY_CODE"
      GROUP BY "Retailer_region_dimension"."REGION_CODE",
        "Retailer_region_dimension"."COUNTRY_KEY",
        "SLS_RETAILER_DIM"."RETAILER_KEY"
      ) "Retailer_site",
      "GOSALESDW"."SLS_SALES_TARG_FACT" "SLS_SALES_TARGET_FACT"
    WHERE "Product"."Product_type_key"           ="SLS_SALES_TARGET_FACT"."PRODUCT_TYPE_KEY"
    AND "SLS_SALES_TARGET_FACT"."RETAILER_KEY"   ="Retailer_site"."Retailer_key"
    AND "SLS_SALES_TARGET_FACT"."RTL_COUNTRY_KEY"="Retailer_site"."Retailer_country_key"
    GROUP BY "Product"."Product_line_code",
      "Retailer_site"."Region_code",
      "Product"."Product_type_key",
      "Retailer_site"."Retailer_country_key",
      "Retailer_site"."Retailer_key"
    ) "T0"
  ) "D3"
ON "D2"."memberUniqueName2"    ="D3"."memberUniqueName2"
AND "D2"."memberUniqueName4"   ="D3"."memberUniqueName4"
AND "D2"."Retailer_country_key"="D3"."Retailer_country_key"
AND "D2"."Retailer_key"        ="D3"."Retailer_key"
AND "D2"."Product_type_key"    ="D3"."Product_type_key"

Oracle Database Concepts

Hi Guys,

This article is intended to strenghten our Oracle database basics.(Not for DBA).Intended for average guys with little knowledge of Oracle physical and Logical structure.Must read if you are planning to go into depth for sql tuning.

If you are working on any database related application.(reporting ,ETL) .you must have writen lot of sql queries.But we hardly know the structure of oracle database how it works.How actually indexes work.What are the parameter that make our query time go high. (slow performance).

To understand these things in details we need to know Oracle basics first ( Physical gets ,Consistent reads) thease are the things that actually determine how your query will work .What is clustertering , what is memory block , what are Bitmap index ,Binary tree indexes .

What is a Index ?

Most people think they know this.Your manager might say ."It's running slow. I think I'll index some of the columns and see if it improves.

Below has been taken from OraFaq -Really a great site to learn :-).Use link to access original article 

Blocks

First you need to understand a block. A block - or page for Microsoft boffins - is the smallest unit of disk that Oracle will read or write. All data in Oracle - tables, indexes, clusters - is stored in blocks. The block size is configurable for any given database but is usually one of 4Kb, 8Kb, 16Kb, or 32Kb. Rows in a table are usually much smaller than this, so many rows will generally fit into a single block. So you never read "just one row"; you will always read the entire block and ignore the rows you don't need. Minimising this wastage is one of the fundamentals of Oracle Performance Tuning.



Oracle uses two different index architectures: b-Tree indexes and bitmap indexes. Cluster indexes, bitmap join indexes, function-based indexes, reverse key indexes and text indexes are all just variations on the two main types. b-Tree is the "normal" index, so we will come back to Bitmap indexes another time.


The "-Tree" in b-Tree ( B stands for balanced & not binary)


A b-Tree index is a data structure in the form of a tree - no surprises there - but it is a tree of database blocks, not rows. Imagine the leaf blocks of the index as the pages of a phone book.



Each page in the book (leaf block in the index) contains many entries, which consist of a name (indexed column value) and an address (ROWID) that tells you the physical location of the telephone (row in the table).

The names on each page are sorted, and the pages - when sorted correctly - contain a complete sorted list of every name and address

A sorted list in a phone book is fine for humans, beacuse we have mastered "the flick" - the ability to fan through the book looking for the page that will contain our target without reading the entire page. When we flick through the phone book, we are just reading the first name on each page, which is usually in a larger font in the page header. Oracle cannot read a single name (row) and ignore the reset of the page (block); it needs to read the entire block.


If we had no thumbs, we may find it convenient to create a separate ordered list containing the first name on each page of the phone book along with the page number. This is how the branch-blocks of an index work; a reduced list that contains the first row of each block plus the address of that block. In a large phone book, this reduced list containing one entry per page will still cover many pages, so the process is repeated, creating the next level up in the index, and so on until we are left with a single page: the root of the tree.

To find the name Gallileo in this b-Tree phone book, we:
Read page 1. This tells us that page 6 starts with Fermat and that page 7 starts with Hawking.
Read page 6. This tells us that page 350 starts with Fyshe and that page 351 starts with Garibaldi.
Read page 350, which is a leaf block; we find Gallileo's address and phone number.

If you look at the original article you can notice his query which qives actual physical address of blocks its accessing.


How are Indexes used?

Indexes have three main uses:

1)  To quickly find specific rows by avoiding a Full Table Scan

We've already seen above how a Unique Scan works. Using the phone book metaphor, it's not hard to understand how a Range Scan works in much the same way to find all people named "Gallileo", or all of the names alphabetically between "Smith" and "Smythe". Range Scans can occur when we use >, <, LIKE, or BETWEEN in a WHERE clause. A range scan will find the first row in the range using the same technique as the Unique Scan, but will then keep reading the index up to the end of the range. It is OK if the range covers many blocks.

2) To avoid a table access altogether

If all we wanted to do when looking up Gallileo in the phone book was to find his address or phone number, the job would be done. However if we wanted to know his date of birth, we'd have to phone and ask. This takes time. If it was something that we needed all the time, like an email address, we could save time by adding it to the phone book.

Oracle does the same thing. If the information is in the index, then it doesn't bother to read the table. It is a reasonably common technique to add columns to an index, not because they will be used as part of the index scan, but because they save a table access. In fact, Oracle may even perform a Fast Full Scan of an index that it cannot use in a Range or Unique scan just to avoid a table access.

3) To avoid a sort

This one is not so well known, largely because it is so poorly documented (and in many cases, unpredicatably implemented by the Optimizer as well). Oracle performs a sort for many reasons: ORDER BY, GROUP BY, DISTINCT, Set operations (eg. UNION), Sort-Merge Joins, uncorrelated IN-subqueries, Analytic Functions). If a sort operation requires rows in the same order as the index, then Oracle may read the table rows via the index. A sort operation is not necessary since the rows are returned in sorted order.

Why Full scans are not Bad ?
Up to now, we've seen how indexes can be good. It's not always the case; sometimes indexes are no help at all, or worse: they make a query slower.

A b-Tree index will be no help at all in a reduced scan unless the WHERE clause compares indexed columns using >, <, LIKE, IN, or BETWEEN operators. A b-Tree index cannot be used to scan for any NOT style operators: eg. !=, NOT IN, NOT LIKE. There are lots of conditions, caveats, and complexities regarding joins, sub-queries, OR predicates, functions (inc. arithmetic and concatenation), and casting that are outside the scope of this article. Consult a good SQL tuning manual.

Much more interesting - and important - are the cases where an index makes a SQL slower. These are particularly common in batch systems that process large quantities of data.

To explain the problem, we need a new metaphor. Imagine a large deciduous tree in your front yard. It's Autumn, and it's your job to pick up all of the leaves on the lawn. Clearly, the fastest way to do this (without a rake, or a leaf-vac...) would be get down on hands and knees with a bag and work your way back and forth over the lawn, stuffing leaves in the bag as you go. This is a Full Table Scan, selecting rows in no particular order, except that they are nearest to hand. This metaphor works on a couple of levels: you would grab leaves in handfuls, not one by one. A Full Table Scan does the same thing: when a bock is read from disk, Oracle caches the next few blocks with the expectation that it will be asked for them very soon

Know your data - Indexes will help to speed up only if 10% data is requested,to read 100%data indexes are very very costly .(exception if the column requested is part of index so that no table access is required)

Just to shake things up a bit (and to feed an undiagnosed obsessive compulsive disorder), you decide to pick up the leaves in order of size. In support of this endeavour, you take a digital photograph of the lawn, write an image analysis program to identify and measure every leaf, then load the results into a Virtual Reality headset that will highlight the smallest leaf left on the lawn. Ingenious, yes; but this is clearly going to take a lot longer than a full table scan because you cover much more distance walking from leaf to leaf.

So obviously Full Table Scan is the faster way to pick up every leaf. But just as obvious is that the index (virtual reality headset) is the faster way to pick up just the smallest leaf, or even the 100 smallest leaves. As the number rises, we approach a break-even point; a number beyond which it is faster to just full table scan. This number varies depending on the table, the index, the database settings, the hardware, and the load on the server; generally it is somewhere between 1% and 10% of the table.

The main reasons for this are:


  • As implied above, reading a table in indexed order means more movement for the disk head.
  • Oracle cannot read single rows. To read a row via an index, the entire block must be read with all but one row discarded. So an index scan of 100 rows would read 100 blocks, but a FTS might read 100 rows in a single block.
  • The db_file_multiblock_read_count setting described earlier means FTS requires fewer visits to the physical disk.
  • Even if none of these things was true, accessing the entire index and the entire table is still more IO than just accessing the table.

So what's the lesson here? Know your data! If your query needs 50% of the rows in the table to resolve your query, an index scan just won't help. Not only should you not bother creating or investigating the existence of an index, you should check to make sure Oracle is not already using an index. There are a number of ways to influence index usage; once again, consult a tuning manual. The exception to this rule - there's always one - is when all of the columns referenced in the SQL are contained in the index. If Oracle does not have to access the table then there is no break-even point; it is generally quicker to scan the index even for 100% of the rows.


Continued ---- Below is a link for Oracle database basics part 2 

Oracle database basics part 2


Good Article on Bitmap indexes and B-Tree indexes 


Link for Good Article on Bitmap indexes (By Oracle )


Very Useful command to check your indexes on table.Cant check one by one in toad(takes too much time)


select
b.uniqueness, a.index_name, a.table_name, a.column_name
from all_ind_columns a, all_indexes b
where a.index_name=b.index_name
and a.table_name = upper('SLS_SALES_FACT')

order by a.table_name, a.index_name, a.column_position;

Disclaimer and Citations 

The content here is taken from various sources found by googling. I have given links wherever possible.For me i dont need in detail information so i have copy pasted the basic information for my use.Also taken are comments from blogs , forum. I have added lot of information according to my understanding of subjects. If anyone finds anything objectionable please leave a comment.

Sql tuning with Bitmap indexes and Star schema transformation

Hi Guys

This Article is relavent only if you are using OLAP (Star schema/Snowflake) .Not if you are using OLTP systems(Online transcation processing) 

General note on Indexes -- B tree index (ones that we use on primary keys) works best when you have unique values. like emp_no . When you dont have unique values they still work good if your query is such that it retrieves less than 20% of data. (eg select * from emp where gender = Male and 20% of your staff is Male so only 20% of rows are retrieved )

If you query retrieves more than 20% data then oracle decides to use full scan instead of indexes. Bitmap indexes are slightly better because oracle still decides to use them even if your query retrieves 40% of total number of rows.

If you query is such that it retrieves more than 40% of rows then oracle will skip bitmap and go for full scan. The advantage bitmap have is rowid are sorted so it know which blocks of data to easily pick


You should remember that bitmap stores only bit value with rowid and the rowid are sorted
  
Rowid
Value of row
Rowid 1
Rowid 2
Rowid 3
Rowid 4
Rowid  5
male
1
1
0
1
0
Female
0
0
0
0
1

When to use B tree or Bitmap indexes

The comparison is not straight forward and it depends on the distribution of data obviously . Like a table which is having emp id (which is unique) distributed randomly wil perform poorly with a B tree index for range scan because of clustering factor . Because of random distribution of data it has to fetch multiple blocks .

Note - the word range scan is used because for equality predicate anyway it has to fetch a single block so it does not make a difference whether bitmap or b tree index

So here is one more question so why this random distribution of data does not apply to bitmap index and it works well . Even bitmap has to get rowid and then go to table to fetch blocks with those row id what is different.

Contrary to popular belief consider a table with 1 million entries and a column for male and female with bitmap index on it. 1/2 million male  and 1/2 million female and you filter by = male will oracle use bitmap index. Most probably it will go for  full scan because even with bitmap it has to get rowid and then fetch those blocks from table

For B tree index oracle uses 5-20% rule that is the data retrieved is within 20% it will go for index otherwiser full table scan is good . Same is case for bitmap but the range is more may be 50%. But consider out of 1 million 800 thousand are males then oracle will prefer full scan instead of bitmap.

So even the male female example for bitmap is not 100% true. You need to understand the data.


Bitmap index are even applied for null values whereas b tree indexes are not applied


If there are two bitmap indexes they can be combined to reduce number of records and then the records can be fetched this is the concept of star transformation

Found some interesting articles on Oracle capabilities for your datawarehouse .How to improve performance

Oracle document on Datawarehouse query improvement

Will write later after implementation.Planning to implement solution

Good Article on Bitmap and B-Tree indexes


http://www.oracle.com/technetwork/articles/sharma-indexes-093638.html

Hints Like /*+ STAR TRANFORMATION */  has huge impact 

Point to be remembered -- Bitmap indexes work together in finding the row required. You cannot have the same columsn with bitmap index and same column with B tree index and compare performance. 

If you have bitmap index on all your dimension seq key in your fact then when you filtered by dimension it can combine those bitmap indexes in finding the correct row. In case of B tree indexes it cannot combine them to get correct row. The more bitmap indexes you have and the more filters you apply on those column result will be faster.

It combines result of each index for zooming to output. 

 
 

Firewall and Tunnelling basics

Hi Guys ,

Few days back i got a mail saying firewall are being replaced. I hardly understood what is a firewall.

Few basics that i knew 

I knew windows has firewall which does not allow you access to ports for someone trying to get access from other machine.Similarly also knew oracle communicate on 1515 port and My sql on some other port .Port 80 for http and firewall monitors these that it .With tunneling you can safely communicate with other machines using ports you like .Like sending http request on some other port so that you can access facebook from inside private networks (office/College) .Nothing much in detail

Below is some more understanding 

Check out this video.It tells you all that firewalls are capable of doing

http://www.youtube.com/watch?v=3_wGDeQOsDE

will write later when time permits