Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 13 ■ PARTITIONING 591 ops$tkyte@ORA10G> CREATE TABLE partitioned 2 ( timestamp date, 3 id int 4 ) 5 PARTITION BY RANGE (timestamp) 6 ( 7 PARTITION part_1 VALUES LESS THAN 8 ( to_date('01-jan-2000','dd-mon-yyyy') ) , 9 PARTITION part_2 VALUES LESS THAN 10 ( to_date('01-jan-2001','dd-mon-yyyy') ) 11 ) 12 / Table created. ops$tkyte@ORA10G> create index partitioned_index 2 on partitioned(id) 3 GLOBAL 4 partition by range(id) 5 ( 6 partition part_1 values less than(1000), 7 partition part_2 values less than (MAXVALUE) 8 ) 9 / Index created. Note the use of MAXVALUE in this index. MAXVALUE can be used in any range partitioned table as well as in the index. It represents an “infinite upper bound” on the range. In our examples so far, we’ve used hard upper bounds on the ranges (values less than ). However, a global index has a requirement that the highest partition (the last partition) must have a partition bound whose value is MAXVALUE. This ensures that all rows in the underlying table can be placed in the index. Now, completing this example, we’ll add our primary key to the table: ops$tkyte@ORA10G> alter table partitioned add constraint 2 partitioned_pk 3 primary key(id) 4 / Table altered. It is not evident from this code that Oracle is using the index we created to enforce the primary key (it is to me because I know that Oracle is using it), so we can prove it by simply trying to drop that index: ops$tkyte@ORA10G> drop index partitioned_index; drop index partitioned_index * ERROR at line 1: ORA-02429: cannot drop index used for enforcement of unique/primary key
592 CHAPTER 13 ■ PARTITIONING To show that Oracle will not allow us to create a nonprefixed global index, we only need try the following: ops$tkyte@ORA10G> create index partitioned_index2 2 on partitioned(timestamp,id) 3 GLOBAL 4 partition by range(id) 5 ( 6 partition part_1 values less than(1000), 7 partition part_2 values less than (MAXVALUE) 8 ) 9 / partition by range(id) * ERROR at line 4: ORA-14038: GLOBAL partitioned index must be prefixed The error message is pretty clear. The global index must be prefixed. So, when would you use a global index? We’ll take a look at two system types, data warehouse and OLTP, and see when they might apply. Data Warehousing and Global Indexes In the past, it used to be that data warehousing and global indexes were pretty much mutually exclusive. A data warehouse implies certain things, such as large amounts of data coming in and going out. Many data warehouses implement a sliding window approach to managing data—that is, drop the oldest partition of a table and add a new partition for the newly loaded data. In the past (Oracle8i and earlier), these systems would have avoided the use of global indexes for a very good reason: lack of availability. It used to be the case that most partition operations, such as dropping an old partition, would invalidate the global indexes, rendering them unusable until they were rebuilt. This could seriously compromise availability. In the following sections, we’ll take a look at what is meant by a sliding window of data and the potential impact of a global index on it. I stress the word “potential” because we’ll also look at how we may get around this issue and how to understand what getting around the issue might imply. Sliding Windows and Indexes The following example implements a classic sliding window of data. In many implementations, data is added to a warehouse over time and the oldest data is aged out. Many times, this data is range partitioned by a date attribute, so that the oldest data is stored together in a single partition, and the newly loaded data is likewise stored together in a new partition. The monthly load process involves • Detaching the old data: The oldest partition is either dropped or exchanged with an empty table (turning the oldest partition into a table) to permit archiving of the old data. • Loading and indexing of the new data: The new data is loaded into a “work” table and indexed and validated.
- Page 586 and 587: CHAPTER 12 ■ DATATYPES 541 suppor
- Page 588 and 589: CHAPTER 12 ■ DATATYPES 543 Concep
- Page 590 and 591: CHAPTER 12 ■ DATATYPES 545 We can
- Page 592 and 593: CHAPTER 12 ■ DATATYPES 547 buffer
- Page 594 and 595: CHAPTER 12 ■ DATATYPES 549 Note t
- Page 596 and 597: CHAPTER 12 ■ DATATYPES 551 13 dbm
- Page 598 and 599: CHAPTER 12 ■ DATATYPES 553 equall
- Page 600 and 601: CHAPTER 12 ■ DATATYPES 555 ROWID/
- Page 602 and 603: CHAPTER 13 ■ ■ ■ Partitioning
- Page 604 and 605: CHAPTER 13 ■ PARTITIONING 559 6 (
- Page 606 and 607: CHAPTER 13 ■ PARTITIONING 561 els
- Page 608 and 609: CHAPTER 13 ■ PARTITIONING 563 BIG
- Page 610 and 611: CHAPTER 13 ■ PARTITIONING 565 Enh
- Page 612 and 613: CHAPTER 13 ■ PARTITIONING 567 Tab
- Page 614 and 615: CHAPTER 13 ■ PARTITIONING 569 tha
- Page 616 and 617: CHAPTER 13 ■ PARTITIONING 571 PAR
- Page 618 and 619: CHAPTER 13 ■ PARTITIONING 573 35
- Page 620 and 621: CHAPTER 13 ■ PARTITIONING 575 If
- Page 622 and 623: CHAPTER 13 ■ PARTITIONING 577 We
- Page 624 and 625: CHAPTER 13 ■ PARTITIONING 579 14
- Page 626 and 627: CHAPTER 13 ■ PARTITIONING 581 ops
- Page 628 and 629: CHAPTER 13 ■ PARTITIONING 583 In
- Page 630 and 631: CHAPTER 13 ■ PARTITIONING 585 ops
- Page 632 and 633: CHAPTER 13 ■ PARTITIONING 587 | S
- Page 634 and 635: CHAPTER 13 ■ PARTITIONING 589 12
- Page 638 and 639: CHAPTER 13 ■ PARTITIONING 593 •
- Page 640 and 641: CHAPTER 13 ■ PARTITIONING 595 Now
- Page 642 and 643: CHAPTER 13 ■ PARTITIONING 597 the
- Page 644 and 645: CHAPTER 13 ■ PARTITIONING 599 imp
- Page 646 and 647: CHAPTER 13 ■ PARTITIONING 601 OLT
- Page 648 and 649: CHAPTER 13 ■ PARTITIONING 603 5 s
- Page 650 and 651: CHAPTER 13 ■ PARTITIONING 605 Sur
- Page 652 and 653: CHAPTER 13 ■ PARTITIONING 607 On
- Page 654 and 655: CHAPTER 13 ■ PARTITIONING 609 Row
- Page 656 and 657: CHAPTER 13 ■ PARTITIONING 611 So,
- Page 658 and 659: CHAPTER 13 ■ PARTITIONING 613 Aud
- Page 660 and 661: CHAPTER 14 ■ ■ ■ Parallel Exe
- Page 662 and 663: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 664 and 665: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 666 and 667: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 668 and 669: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 670 and 671: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 672 and 673: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 674 and 675: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 676 and 677: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 678 and 679: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 680 and 681: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 682 and 683: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 684 and 685: CHAPTER 14 ■ PARALLEL EXECUTION 6
592<br />
CHAPTER 13 ■ PARTITIONING<br />
To show that <strong>Oracle</strong> will not allow us to create a nonprefixed global index, we only need<br />
try the following:<br />
ops$tkyte@ORA10G> create index partitioned_index2<br />
2 on partitioned(timestamp,id)<br />
3 GLOBAL<br />
4 partition by range(id)<br />
5 (<br />
6 partition part_1 values less than(1000),<br />
7 partition part_2 values less than (MAXVALUE)<br />
8 )<br />
9 /<br />
partition by range(id)<br />
*<br />
ERROR at line 4:<br />
ORA-14038: GLOBAL partitioned index must be prefixed<br />
The error message is pretty clear. The global index must be prefixed. So, when would you<br />
use a global index? We’ll take a look at two system types, data warehouse <strong>and</strong> OLTP, <strong>and</strong> see<br />
when they might apply.<br />
Data Warehousing <strong>and</strong> Global Indexes<br />
In the past, it used to be that data warehousing <strong>and</strong> global indexes were pretty much mutually<br />
exclusive. A data warehouse implies certain things, such as large amounts of data coming in<br />
<strong>and</strong> going out. Many data warehouses implement a sliding window approach to managing<br />
data—that is, drop the oldest partition of a table <strong>and</strong> add a new partition for the newly loaded<br />
data. In the past (<strong>Oracle</strong>8i <strong>and</strong> earlier), these systems would have avoided the use of global<br />
indexes for a very good reason: lack of availability. It used to be the case that most partition<br />
operations, such as dropping an old partition, would invalidate the global indexes, rendering<br />
them unusable until they were rebuilt. This could seriously compromise availability.<br />
In the following sections, we’ll take a look at what is meant by a sliding window of data<br />
<strong>and</strong> the potential impact of a global index on it. I stress the word “potential” because we’ll also<br />
look at how we may get around this issue <strong>and</strong> how to underst<strong>and</strong> what getting around the<br />
issue might imply.<br />
Sliding Windows <strong>and</strong> Indexes<br />
The following example implements a classic sliding window of data. In many implementations,<br />
data is added to a warehouse over time <strong>and</strong> the oldest data is aged out. Many times, this<br />
data is range partitioned by a date attribute, so that the oldest data is stored together in a single<br />
partition, <strong>and</strong> the newly loaded data is likewise stored together in a new partition. The<br />
monthly load process involves<br />
• Detaching the old data: The oldest partition is either dropped or exchanged with an<br />
empty table (turning the oldest partition into a table) to permit archiving of the old<br />
data.<br />
• Loading <strong>and</strong> indexing of the new data: The new data is loaded into a “work” table <strong>and</strong><br />
indexed <strong>and</strong> validated.