# Oracle Bitmap Index



## BaseBallBatBoy (10. Februar 2014)

Hallo

Ich habe eine Tabelle mit einer Spalte 'VERARBEITET' NUMBER. Die Spalte wird mit 0 (noch nicht verarbeitet) oder 1 (bereits verarbeitet) befüllt. Ca. 95% sind 1 und 5% 0. Initial hat die Tabelle ca. 50 Mio Records. Selektiert wird oft mit WHERE VERARBEITET = 0 (also nur was noch verarbeitet werden muss). Wenn verarbeitet wurde, werden entsprechend dieses Rows auf VERARBEITET = 1 upgedated. Neue Inserts in die Tabelle (jeweils mit VERARBEITET = 0) gibt es pro Tag ca. 2% zusätzlich. 

Aufgrund der Kardinalität und der vergleichsweise kleinen Anzahl 0 (weniger als 20%) denke ich, dass ein Bitmap Index gut wäre. Hingegen bin ich nicht sicher ob die Updates und Inserts die ganzen Vorteile wieder ausbremsen. In dem Szenario, welcher Index wäre ideal?

Gruss
BBBB


----------



## Yaslaw (10. Februar 2014)

Ich würde ebenfalls ein Bitmap Index machen.
Ich kenne gerade keine Nachteile biem INSERT oder UPDATE, der Bitmap-Index speziefisch ist.


----------



## BaseBallBatBoy (10. Februar 2014)

Ok, danke für den Input.

Ich frage deshalb:
http://docs.oracle.com/cd/E11882_01/server.112/e25789/indexiot.htm#CNCPT1182
Unter Bitmap Indexes
"
Bitmap indexes are primarily designed for data warehousing or environments in which queries reference many columns in an ad hoc fashion. Situations that may call for a bitmap index include:

The indexed columns have low cardinality, that is, the number of distinct values is small compared to the number of table rows.

The indexed table is either read-only or not subject to significant modification by DML statements.
"

Erster Punkt: ja, das ist so. Zweiter Punkt: read-only nein, "not subject to significant modification by DML statements" was ist denn genau signifikant? 

Aber ich denke die Vorteile überwiegen hier die Nachteile.


----------



## MPr (10. Februar 2014)

obwohl die Frage als beantwortet gilt, gäbe es aus meiner Sicht noch ein paar Dinge zu ergänzen:

1. im Fall eines B*Tree-Index führt eine DML-Operation nur zu einem Lock auf dem einzelnen Satz. Im Fall eines Bitmap Index betrifft das Lock hingegen alle Datensätze, die vom zugehörigen row piece des Index abgedeckt werden - und das können unter Umständen recht viele Sätze sein. Insofern sind Bitmap Indizes klassischerweise eine Option für Data Warehouses und nicht für OLTP-Systeme (wobei der Systemtyp natürlich nicht entscheidend ist, sondern die Art der zugehörigen DML-Operationen): große Ladeoperationen sind kein Problem (wobei man dann die Indizes oft auch ausschaltet und nach dem Laden neu aufbaut), aber kleine konkurrierende Transaktionen können eines sein.

2. Die Aussage, dass Bitmap Indizes besonders gut für Spalten mit wenigen unterschiedlichen Werten geeignet sind, ist nicht unbedingt falsch (und findet sich auch in der Oracle Dokumentation an verschiedenen Stellen) - ganz passend ist sie aber auch nicht: auch ein Bitmap Index ist nur dann ein geeigneter Zugriffsmechanismus, wenn er eine hohe Selektivität besitzt. In vielen Fällen kann die Kombination mehrerer Bitmap Indizes diese Selektivität liefern, aber ein einzelner Bitmap Index ist nur für die selteneren enthaltenen Werte ein geeigneter Zugriff - im gegebenen Fall also höchstens für verarbeitet = 0 (wobei 5% je nach Clusterung der Werte schon ziemlich viel sein kann, da ein solcher Anteil bereits einen Zugriff auf alle Tabellenblocks erforderlich machen könnte, was über Full Table Scan schneller erfolgen könnte).

3. Ein Bitmap Index kann je nach Werte-Clusterung sehr gut komprimiert werden, was auch einen schnellen Aufbau ermöglicht. Allerdings kann man auch einen B*Tree-Index kompakt halten, dann nämlich, wenn man nur die relevanten Werte indiziert. Ein schönes Beispiel dafür findet man bei Richard Foote (https://richardfoote.wordpress.com/2008/01/28/index-only-values-of-interest-little-wonder/), der eigentlich immer die erste Adresse ist, wenn es um Oracle Indizes geht (wobei man beim Thema Bitmap Index Julian Dykes Präsentation http://www.juliandyke.com/Presentations/Presentations.html#BitmapIndexInternals nicht unerwähnt lassen sollte)

Gruß

MPR


----------



## BaseBallBatBoy (11. Februar 2014)

Danke MPr. Also würdest du in dem Fall eher B*Tree anstelle Bitmap verwenden?


----------



## MPr (11. Februar 2014)

wahrscheinlich würde ich mit beiden Varianten testen (am besten in einem Testsystem oder zumindest einer Testtabelle), ehe ich mich entscheide. Mein Favorit wäre allerdings der von Richard Foote beschriebene selektive Index (den auch Tom Kyte regelmäßig empfiehlt), da die Beschreibung des Standardanwendungsfalls ziemlich genau passt: 


> The classic scenario is where we may have a flag or status field denoting “current”, “live”, “not yet processed”, etc. rows and our main transactional queries are only interested in these relatively few rows.


- allerdings macht ein solcher funktionsbasierter Index eine Anpassung der Zugriffe erforderlich. Wenn die Zahl der relevanten Datensätze aber tatsächlich relativ klein ist, dann wäre ein solcher Index wahrscheinlich noch kompakter als ein Bitmap Index.


----------



## Yaslaw (11. Februar 2014)

Hast du einen guten Link um mehr über diesen selektiven Index zu lernen? Ich kenne ihn noch nicht


----------



## MPr (11. Februar 2014)

das beste Beispiel, das ich gefunden habe, ist das von Richard Foote: https://richardfoote.wordpress.com/2008/01/28/index-only-values-of-interest-little-wonder/. Ein weiterer Link wäre: http://www.oracle.com/technetwork/issue-archive/o34asktom-100050.html. Letztlich zieht man einfach einen Vorteil aus der Tatsache, dass ein B*Tree-Index mit nur einer Spalte NULL-Werte nicht enthält - alternativ könnte man also auch die Statusangaben 1 und NULL (statt 0) für "verarbeitet" verwenden, aber wenn die Daten schon mal da sind, ist der FBI, der die 0 in einen NULL-Wert umbaut, ein netter Trick.


----------

