Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 11 ■ INDEXES 427 We then create an IDX_STATS table in which to save INDEX_STATS information, and we label the rows in the table as “noncompressed”: ops$tkyte@ORA10G> create table idx_stats 2 as 3 select 'noncompressed' what, a.* 4 from index_stats a; Table created. Now, we could realize that the OWNER component is repeated many times, meaning that a single index block in this index will have dozens of entries, as shown in Figure 11-2. Figure 11-2. Index block with OWNER column repeated We could factor the repeated OWNER column out of this, resulting in a block that looks more like Figure 11-3. Figure 11-3. Index block with OWNER column factored out In Figure 11-3, the owner name appears once on the leaf block—not once per repeated entry. We run the following script, passing in the number 1, to re-create the scenario whereby the index is using compression on just the leading column: drop index t_idx; create index t_idx on t(owner,object_type,object_name) compress &1;
428 CHAPTER 11 ■ INDEXES analyze index t_idx validate structure; insert into idx_stats select 'compress &1', a.* from index_stats a; For comparison reasons, we run this script not only with one column, but also two and three compressed columns, to see what happens. At the end, we query IDX_STATS and should observe this: ops$tkyte@ORA10G> select what, height, lf_blks, br_blks, 2 btree_space, opt_cmpr_count, opt_cmpr_pctsave 3 from idx_stats 4 / WHAT HEIGHT LF_BLKS BR_BLKS BTREE_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE ------------- ------- -------- ------- ----------- -------------- ---------------- noncompressed 3 337 3 2718736 2 28 compress 1 3 300 3 2421684 2 19 compress 2 2 240 1 1926108 2 0 compress 3 3 375 3 3021084 2 35 We see that the COMPRESS 1 index is about 89 percent the size of the noncompressed index (comparing BTREE_SPACE). The number of leaf blocks has decreased measurably. Further, when we use COMPRESS 2, the savings are even more impressive. The resulting index is about 70 percent the size of the original, and so much data is able to be placed on individual blocks that the height of the index actually decreased from 3 to 2. In fact, using the column OPT_CMPR_ PCTSAVE, which stands for optimum compression percent saved or the expected savings from compression, we could have guessed the size of the COMPRESS 2 index: ops$tkyte@ORA10G> select 2718736*(1-0.28) from dual; 2718736*(1-0.28) ---------------- 1957489.92 ■Note The ANALYZE command against the noncompressed index populated the OPT_CMPR_ PCTSAVE/OPT_CMPR_COUNT columns and estimated a 28 percent savings with COMPRESS 2, and we achieved just about exactly that. But notice what happens with COMPRESS 3. The resulting index is actually larger: 110 percent the size of the original index. This is due to the fact that each repeated prefix we remove saves the space of N copies, but adds 4 bytes of overhead on the leaf block as part of the compression scheme. By adding in the OBJECT_NAME column to the compressed key, we made that key unique—in this case, meaning there were no duplicate copies to factor out. Therefore,
- Page 421 and 422: 376 CHAPTER 10 ■ DATABASE TABLES
- Page 423 and 424: 378 CHAPTER 10 ■ DATABASE TABLES
- Page 425 and 426: 380 CHAPTER 10 ■ DATABASE TABLES
- Page 427 and 428: 382 CHAPTER 10 ■ DATABASE TABLES
- Page 429 and 430: 384 CHAPTER 10 ■ DATABASE TABLES
- Page 431 and 432: 386 CHAPTER 10 ■ DATABASE TABLES
- Page 433 and 434: 388 CHAPTER 10 ■ DATABASE TABLES
- Page 435 and 436: 390 CHAPTER 10 ■ DATABASE TABLES
- Page 437 and 438: 392 CHAPTER 10 ■ DATABASE TABLES
- Page 439 and 440: 394 CHAPTER 10 ■ DATABASE TABLES
- Page 441 and 442: 396 CHAPTER 10 ■ DATABASE TABLES
- Page 443 and 444: 398 CHAPTER 10 ■ DATABASE TABLES
- Page 445 and 446: 400 CHAPTER 10 ■ DATABASE TABLES
- Page 447 and 448: 402 CHAPTER 10 ■ DATABASE TABLES
- Page 449 and 450: 404 CHAPTER 10 ■ DATABASE TABLES
- Page 451 and 452: 406 CHAPTER 10 ■ DATABASE TABLES
- Page 453 and 454: 408 CHAPTER 10 ■ DATABASE TABLES
- Page 455 and 456: 410 CHAPTER 10 ■ DATABASE TABLES
- Page 457 and 458: 412 CHAPTER 10 ■ DATABASE TABLES
- Page 459 and 460: 414 CHAPTER 10 ■ DATABASE TABLES
- Page 461 and 462: 416 CHAPTER 10 ■ DATABASE TABLES
- Page 463 and 464: 418 CHAPTER 10 ■ DATABASE TABLES
- Page 466 and 467: CHAPTER 11 ■ ■ ■ Indexes Inde
- Page 468 and 469: CHAPTER 11 ■ INDEXES 423 value of
- Page 470 and 471: CHAPTER 11 ■ INDEXES 425 One of t
- Page 474 and 475: CHAPTER 11 ■ INDEXES 429 we ended
- Page 476 and 477: CHAPTER 11 ■ INDEXES 431 The data
- Page 478 and 479: CHAPTER 11 ■ INDEXES 433 if ( (++
- Page 480 and 481: CHAPTER 11 ■ INDEXES 435 Table 11
- Page 482 and 483: CHAPTER 11 ■ INDEXES 437 When Sho
- Page 484 and 485: CHAPTER 11 ■ INDEXES 439 an 8KB b
- Page 486 and 487: CHAPTER 11 ■ INDEXES 441 select *
- Page 488 and 489: CHAPTER 11 ■ INDEXES 443 select *
- Page 490 and 491: CHAPTER 11 ■ INDEXES 445 Indicate
- Page 492 and 493: CHAPTER 11 ■ INDEXES 447 an index
- Page 494 and 495: CHAPTER 11 ■ INDEXES 449 Table 11
- Page 496 and 497: CHAPTER 11 ■ INDEXES 451 9 1, 'M'
- Page 498 and 499: CHAPTER 11 ■ INDEXES 453 column w
- Page 500 and 501: CHAPTER 11 ■ INDEXES 455 Bitmap j
- Page 502 and 503: CHAPTER 11 ■ INDEXES 457 INSERT a
- Page 504 and 505: CHAPTER 11 ■ INDEXES 459 7 l_last
- Page 506 and 507: CHAPTER 11 ■ INDEXES 461 ops$tkyt
- Page 508 and 509: CHAPTER 11 ■ INDEXES 463 If we co
- Page 510 and 511: CHAPTER 11 ■ INDEXES 465 ops$tkyt
- Page 512 and 513: CHAPTER 11 ■ INDEXES 467 Caveat o
- Page 514 and 515: CHAPTER 11 ■ INDEXES 469 ops$tkyt
- Page 516 and 517: CHAPTER 11 ■ INDEXES 471 Frequent
- Page 518 and 519: CHAPTER 11 ■ INDEXES 473 select *
- Page 520 and 521: CHAPTER 11 ■ INDEXES 475 If you s
428<br />
CHAPTER 11 ■ INDEXES<br />
analyze index t_idx validate structure;<br />
insert into idx_stats<br />
select 'compress &1', a.*<br />
from index_stats a;<br />
For comparison reasons, we run this script not only with one column, but also two <strong>and</strong><br />
three compressed columns, to see what happens. At the end, we query IDX_STATS <strong>and</strong> should<br />
observe this:<br />
ops$tkyte@ORA10G> select what, height, lf_blks, br_blks,<br />
2 btree_space, opt_cmpr_count, opt_cmpr_pctsave<br />
3 from idx_stats<br />
4 /<br />
WHAT<br />
HEIGHT LF_BLKS BR_BLKS BTREE_SPACE OPT_CMPR_COUNT OPT_CMPR_PCTSAVE<br />
------------- ------- -------- ------- ----------- -------------- ----------------<br />
noncompressed 3 337 3 2718736 2 28<br />
compress 1 3 300 3 2421684 2 19<br />
compress 2 2 240 1 1926108 2 0<br />
compress 3 3 375 3 3021084 2 35<br />
We see that the COMPRESS 1 index is about 89 percent the size of the noncompressed index<br />
(comparing BTREE_SPACE). The number of leaf blocks has decreased measurably. Further, when<br />
we use COMPRESS 2, the savings are even more impressive. The resulting index is about 70 percent<br />
the size of the original, <strong>and</strong> so much data is able to be placed on individual blocks that<br />
the height of the index actually decreased from 3 to 2. In fact, using the column OPT_CMPR_<br />
PCTSAVE, which st<strong>and</strong>s for optimum compression percent saved or the expected savings from<br />
compression, we could have guessed the size of the COMPRESS 2 index:<br />
ops$tkyte@ORA10G> select 2718736*(1-0.28) from dual;<br />
2718736*(1-0.28)<br />
----------------<br />
1957489.92<br />
■Note The ANALYZE comm<strong>and</strong> against the noncompressed index populated the OPT_CMPR_<br />
PCTSAVE/OPT_CMPR_COUNT columns <strong>and</strong> estimated a 28 percent savings with COMPRESS 2, <strong>and</strong><br />
we achieved just about exactly that.<br />
But notice what happens with COMPRESS 3. The resulting index is actually larger: 110 percent<br />
the size of the original index. This is due to the fact that each repeated prefix we remove<br />
saves the space of N copies, but adds 4 bytes of overhead on the leaf block as part of the<br />
compression scheme. By adding in the OBJECT_NAME column to the compressed key, we made<br />
that key unique—in this case, meaning there were no duplicate copies to factor out. Therefore,