Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 13 ■ PARTITIONING 595 Now we’re ready to update the “live” data using an exchange partition: ops$tkyte@ORA10G> alter table partitioned 2 exchange partition fy_2004 3 with table fy_2004 4 including indexes 5 without validation 6 / Table altered. ops$tkyte@ORA10G> alter table partitioned 2 drop partition fy_2004 3 / Table altered. This is all we need to do to “age” the old data out. We turned the partition into a full table and the empty table into a partition. This was a simple data dictionary update. No large amount of I/O took place—it just happened. We can now export that FY_2004 table (perhaps using a transportable tablespace) out of our database for archival purposes. We could reattach it quickly if we ever needed to. Next, we want to slide in the new data: ops$tkyte@ORA10G> alter table partitioned 2 add partition fy_2006 3 values less than ( to_date('01-jan-2007','dd-mon-yyyy') ) 4 / Table altered. ops$tkyte@ORA10G> alter table partitioned 2 exchange partition fy_2006 3 with table fy_2006 4 including indexes 5 without validation 6 / Table altered. Again, this was instantaneous; it was accomplished via simple data dictionary updates. Adding the empty partition took very little time to process. Then, we exchange the newly created empty partition with the full table, and the full table with the empty partition, and that operation is performed quickly as well. The new data is online. Looking at our indexes, however, we’ll find the following: ops$tkyte@ORA10G> select index_name, status from user_indexes; INDEX_NAME STATUS ------------------------------ -------- FY_2006_IDX VALID FY_2004_IDX VALID PARTITIONED_IDX_GLOBAL UNUSABLE
596 CHAPTER 13 ■ PARTITIONING The global index is, of course, unusable after this operation. Since each index partition can point to any table partition, and we just took away a partition and added a partition, that index is invalid. It has entries that point into the partition we dropped. It has no entries that point into the partition we just added. Any query that would make use of this index either will fail and not execute or, if we skip unusable indexes, the query’s performance will be negatively impacted by not being able to use the index: ops$tkyte@ORA10G> set autotrace on explain ops$tkyte@ORA10G> select /*+ index( partitioned PARTITIONED_IDX_GLOBAL ) */ count(*) 2 from partitioned 3 where timestamp between sysdate-50 and sysdate; select /*+ index( partitioned PARTITIONED_IDX_GLOBAL ) */ count(*) * ERROR at line 1: ORA-01502: index 'OPS$TKYTE.PARTITIONED_IDX_GLOBAL' or partition of such index is in unusable state ops$tkyte@ORA10G> select count(*) 2 from partitioned 3 where timestamp between sysdate-50 and sysdate; COUNT(*) ---------- 6750 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=59 Card=1 Bytes=9) 1 0 SORT (AGGREGATE) 2 1 FILTER 3 2 PARTITION RANGE (ITERATOR) (Cost=59 Card=7234 Bytes=65106) 4 3 TABLE ACCESS (FULL) OF 'PARTITIONED' (TABLE) (Cost=59 Card=7234 ops$tkyte@ORA10G> set autotrace off So, our choices after performing this partition operation with global indexes are • Skip the index, either transparently as Oracle 10g is doing in this example or by setting the session parameter SKIP_UNUSABLE_INDEXES=TRUE in 9i (Oracle 10g defaults this setting to TRUE). But then we lose the performance the index was giving us. • Have the query receive an error, as it would in 9i unless SKIP_UNUSABLE_INDEXES were set to FALSE, and as would any query in 10g that explicitly requests to use a hint. We need to rebuild this index to make the data truly usable again. The sliding window process, which so far has resulted in virtually no downtime, will now take a very long time to complete while we rebuild the global index. Runtime query performance of queries that relied on these indexes will be negatively affected during this time—either
- 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 636 and 637: CHAPTER 13 ■ PARTITIONING 591 ops
- Page 638 and 639: CHAPTER 13 ■ PARTITIONING 593 •
- 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
- Page 686 and 687: CHAPTER 14 ■ PARALLEL EXECUTION 6
- Page 688 and 689: CHAPTER 14 ■ PARALLEL EXECUTION 6
CHAPTER 13 ■ PARTITIONING 595<br />
Now we’re ready to update the “live” data using an exchange partition:<br />
ops$tkyte@ORA10G> alter table partitioned<br />
2 exchange partition fy_2004<br />
3 with table fy_2004<br />
4 including indexes<br />
5 without validation<br />
6 /<br />
Table altered.<br />
ops$tkyte@ORA10G> alter table partitioned<br />
2 drop partition fy_2004<br />
3 /<br />
Table altered.<br />
This is all we need to do to “age” the old data out. We turned the partition into a full<br />
table <strong>and</strong> the empty table into a partition. This was a simple data dictionary update. No large<br />
amount of I/O took place—it just happened. We can now export that FY_2004 table (perhaps<br />
using a transportable tablespace) out of our database for archival purposes. We could reattach<br />
it quickly if we ever needed to.<br />
Next, we want to slide in the new data:<br />
ops$tkyte@ORA10G> alter table partitioned<br />
2 add partition fy_2006<br />
3 values less than ( to_date('01-jan-2007','dd-mon-yyyy') )<br />
4 /<br />
Table altered.<br />
ops$tkyte@ORA10G> alter table partitioned<br />
2 exchange partition fy_2006<br />
3 with table fy_2006<br />
4 including indexes<br />
5 without validation<br />
6 /<br />
Table altered.<br />
Again, this was instantaneous; it was accomplished via simple data dictionary updates.<br />
Adding the empty partition took very little time to process. Then, we exchange the newly created<br />
empty partition with the full table, <strong>and</strong> the full table with the empty partition, <strong>and</strong> that<br />
operation is performed quickly as well. The new data is online.<br />
Looking at our indexes, however, we’ll find the following:<br />
ops$tkyte@ORA10G> select index_name, status from user_indexes;<br />
INDEX_NAME<br />
STATUS<br />
------------------------------ --------<br />
FY_2006_IDX<br />
VALID<br />
FY_2004_IDX<br />
VALID<br />
PARTITIONED_IDX_GLOBAL UNUSABLE