Sonntag, Juni 19, 2011

Hash Partitioning

Ich habe mich schon häufiger gefragt, wozu HASH Partitioning eigentlich gut sein könnte, war aber immer zu träge, der Frage im Detail nachzugehen. Das soll nun korrigiert werden. Dazu zunächst die Definition des Concept Guides (11.2):
In hash partitioning, the database maps rows to partitions based on a hashing algorithm that the database applies to the user-specified partitioning key. The destination of a row is determined by the internal hash function applied to the row by the database. The hashing algorithm is designed to evenly distributes rows across devices so that each partition contains about the same number of rows.

Hash partitioning is useful for dividing large tables to increase manageability. Instead of one large table to manage, you have several smaller pieces. The loss of a single hash partition does not affect the remaining partitions and can be recovered independently. Hash partitioning is also useful in OLTP systems with high update contention. For example, a segment is divided into several pieces, each of which is updated, instead of a single segment that experiences contention.
Demnach gilt:
  • die Zuordnung von Sätzen zu Partitionen wird über eine Hash Funktion gesteuert (was jetzt keine große Überraschung ist), die auf den Partition Key angewandt wird
  • Hash Partitioning dient zum Aufteilen einer großen Datenmenge auf mehrere Partitionen, die besser administrierbar sind (und die Gefahr von Contention vermindern)
Der VLDB Guide (wieder 11.2) liefert noch den ergänzenden Hinweis: "Hash partitioning is also an easy-to-use alternative to range partitioning, especially when the data to be partitioned is not historical or has no obvious partitioning key." Außerdem erfährt man dort: "You cannot change the hashing algorithms used by partitioning." Hash Partitioning ist also offenbar vor allem (bzw. fast ausschließlich) dann interessant, wenn der Partition Key keine vernünftige Range- oder List-Partitionierung gestattet. Das macht das Verfahren für die meisten praktischen Fälle, mit denen ich bisher konfrontiert wurde, ziemlich uninteressant - fast immer gibt der Partition Key eine sinnvollere Verteilungsstrategie her. Darüber hinaus habe ich bei Tom Kyte in Expert Oracle Database Architecture gerade noch mal den Hinweis gelesen, dass man für die Anzahl von Hash Partitionen immer eine "power of 2" verwenden sollte, da sonst die Gleichverteilung auf der Strecke bleiben kann. Nun stammt meine Ausgabe des Buchs aus dem Jahr 2005 und behandelt die Versionen 9 und 10, weshalb ich mal kurz überprüfen will, ob diese Aussage auch für 11.2 noch gültig ist. Und, um der Trägheit noch stärker entgegen zu wirken, verwende ich nicht das elegante Testverfahren des Herrn Kyte, sondern extemporiere etwas weitaus Simpleres (nämlich ein Script, das mir eine Anaylsequery generiert):

-- test_hash_partitioning.sql
drop table test_hash_partitioned;

create table test_hash_partitioned
partition by hash(id)
partitions &&partition_count
as
select rownum id
  from dual
connect by level <= 32000;

select 'select ''' || partition_name || ''' partition_name,  count(*) row_count from '
       || table_name || ' partition (' || partition_name || ')' part1
     , case when partition_position < &partition_count then ' union all ' else ';' end part2
  from user_tab_partitions
 where table_name = 'TEST_HASH_PARTITIONED';
Das Ergebnis der generierten Hilfsquery lautet für den Fall mit 4 Partitionen:
PARTITIO  ROW_COUNT
-------- ----------
SYS_P481       7893
SYS_P482       7916
SYS_P483       8246
SYS_P484       7945
Das kann als Gleichverteilung durchgehen. Fall 2: 5 Partitionen:
PARTITIO  ROW_COUNT
-------- ----------
SYS_P485       3981
SYS_P486       7916
SYS_P487       8246
SYS_P488       7945
SYS_P489       3912
Das wiederum ist nicht gleichverteilt, aber entspricht sehr genau dem Ergebnis beim Herrn Kyte. Hier noch die Werte für die Fälle mit 6, 7 und 8 Partitionen:
-- 6 Partitionen
PARTITIO  ROW_COUNT
-------- ----------
SYS_P510       3981
SYS_P511       3988
SYS_P512       8246
SYS_P513       7945
SYS_P514       3912
SYS_P515       3928

-- 7 Partitionen
PARTITIO  ROW_COUNT
-------- ----------
SYS_P516       3981
SYS_P517       3988
SYS_P518       4112
SYS_P519       7945
SYS_P520       3912
SYS_P521       3928
SYS_P522       4134

-- 8 Partitionen
PARTITIO  ROW_COUNT
-------- ----------
SYS_P523       3981
SYS_P524       3988
SYS_P525       4112
SYS_P526       3954
SYS_P527       3912
SYS_P528       3928
SYS_P529       4134
SYS_P530       3991

Fall 8 ist dann wieder gleichverteilt, was zeigt, dass Tom Kytes Aussagen in diesem Punkt auf für 11.2.0.1 unverändert gelten.

Keine Kommentare:

Kommentar veröffentlichen