Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 11 ■ INDEXES 469 ops$tkyte@ORA10GR1> select to_char( to_date('2005','YYYY'), 2 'DD-Mon-YYYY HH24:MI:SS' ) 3 from dual; TO_CHAR(TO_DATE('200 -------------------- 01-May-2005 00:00:00 the YYYY format will return May 1, in June it will return June 1, and so on. It turns out that TO_DATE, when used with YYYY, is not deterministic! That is why the index cannot be created: it would only work correctly in the month you created it in (or insert/updated a row in). So, it is due to the user environment, which includes the current date itself. To use TO_DATE in a function-based index, you must use a date format that is unambiguous and deterministic—regardless of what day it is currently. Function-Based Indexes Wrap-Up Function-based indexes are easy to use and implement, and they provide immediate value. They can be used to speed up existing applications without changing any of their logic or queries. Many orders of magnitude improvement may be observed. You can use them to precompute complex values without using a trigger. Additionally, the optimizer can estimate selectivity more accurately if the expressions are materialized in a function-based index. You can use function-based indexes to selectively index only rows of interest as demonstrated earlier with the PROCESSED_FLAG example. You can, in effect, index a WHERE clause using that technique. Lastly, we explored how to use function-based indexes to implement a certain kind of integrity constraint: selective uniqueness (e.g., “The fields X,Y, and Z must be unique when some condition is true”). Function-based indexes will affect the performance of inserts and updates. Whether or not that warning is relevant to you is something you must decide. If you insert and very infrequently query the data, this might not be an appropriate feature for you. On the other hand, keep in mind that you typically insert a row once and you query it thousands of times. The performance hit on the insert (which your individual end user will probably never notice) may be offset many thousands of times by speeding up the queries. In general, the pros heavily outweigh any of the cons in this case. Application Domain Indexes Application domain indexes are what Oracle calls extensible indexing. They allow you to create your own index structures that work just like indexes supplied by Oracle. When someone issues a CREATE INDEX statement using your index type, Oracle will run your code to generate the index. If someone analyzes the index to compute statistics on it, Oracle will execute your code to generate statistics in whatever format you care to store them in. When Oracle parses a query and develops a query plan that may make use of your index, Oracle will ask you how costly this function is to perform as it is evaluating the different plans. In short, application domain indexes give you the ability to implement a new index type that does not exist in the database as of yet. For example, if you develop software that analyzes images stored in the database, and you produce information about the images, such as the colors found in them,
470 CHAPTER 11 ■ INDEXES you could create your own image index. As images are added to the database, your code is invoked to extract the colors from the images and store them somewhere (wherever you want to store them). At query time, when the user asks for all “blue images,” Oracle will ask you to provide the answer from your index when appropriate. The best example of this is Oracle’s own text index. This index is used to provide keyword searching on large text items. You may create a simple text index like this: ops$tkyte@ORA10G> create index myindex on mytable(docs) 2 indextype is ctxsys.context 3 / Index created. and then use the text operators the creators of that index introduced into the SQL language: select * from mytable where contains( docs, 'some words' ) > 0; It will even respond to commands such as the following: ops$tkyte@ORA10GR1> begin 2 dbms_stats.gather_index_stats( user, 'MYINDEX' ); 3 end; 4 / PL/SQL procedure successfully completed. It will participate with the optimizer at runtime to determine the relative cost of using a text index over some other index or a full scan. The interesting thing about all of this is that you or I could have developed this index. The implementation of the text index was done without “inside kernel knowledge.” It was done using the dedicated, documented, and exposed API. The Oracle database kernel is not aware of how the text index is stored (the APIs store it in many physical database tables per index created). Oracle is not aware of the processing that takes place when a new row is inserted. Oracle text is really an application built on top of the database, but in a wholly integrated fashion. To you and me, it looks just like any other Oracle database kernel function, but it is not. I personally have not found the need to go and build a new exotic type of index structure. I see this particular feature as being of use mostly to third-party solution providers that have innovative indexing techniques. I think the most interesting thing about application domain indexes is that they allow others to supply new indexing technology I can use in my applications. Most people will never make use of this particular API to build a new index type, but most of us will use the end results. Virtually every application I work on seems to have some text associated with it, XML to be dealt with, or images to be stored and categorized. The interMedia set of functionality, implemented using the Application Domain Indexing feature, provides these capabilities. As time passes, the set of available index types grows. We’ll take a more in-depth look at the text index in a subsequent chapter.
- 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 472 and 473: CHAPTER 11 ■ INDEXES 427 We then
- 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 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
- Page 522 and 523: CHAPTER 11 ■ INDEXES 477 we’ll
- Page 524 and 525: CHAPTER 11 ■ INDEXES 479 Predicat
- Page 526 and 527: CHAPTER 11 ■ INDEXES 481 ops$tkyt
- Page 528 and 529: CHAPTER 11 ■ INDEXES 483 ops$tkyt
- Page 530 and 531: CHAPTER 11 ■ INDEXES 485 This dem
- Page 532 and 533: CHAPTER 11 ■ INDEXES 487 SELECT /
- Page 534 and 535: CHAPTER 12 ■ ■ ■ Datatypes Ch
- Page 536 and 537: CHAPTER 12 ■ DATATYPES 491 • TI
- Page 538 and 539: CHAPTER 12 ■ DATATYPES 493 (in th
- Page 540 and 541: CHAPTER 12 ■ DATATYPES 495 That d
- Page 542 and 543: CHAPTER 12 ■ DATATYPES 497 ops$tk
- Page 544 and 545: CHAPTER 12 ■ DATATYPES 499 Table
- Page 546 and 547: CHAPTER 12 ■ DATATYPES 501 The IN
- Page 548 and 549: CHAPTER 12 ■ DATATYPES 503 ops$tk
- Page 550 and 551: CHAPTER 12 ■ DATATYPES 505 • BI
- Page 552 and 553: CHAPTER 12 ■ DATATYPES 507 NUMBER
- Page 554 and 555: CHAPTER 12 ■ DATATYPES 509 MSG NU
- Page 556 and 557: CHAPTER 12 ■ DATATYPES 511 They a
- Page 558 and 559: CHAPTER 12 ■ DATATYPES 513 ■Not
- Page 560 and 561: CHAPTER 12 ■ DATATYPES 515 Coping
- Page 562 and 563: CHAPTER 12 ■ DATATYPES 517 Note t
470<br />
CHAPTER 11 ■ INDEXES<br />
you could create your own image index. As images are added to the database, your code is<br />
invoked to extract the colors from the images <strong>and</strong> store them somewhere (wherever you want<br />
to store them). At query time, when the user asks for all “blue images,” <strong>Oracle</strong> will ask you to<br />
provide the answer from your index when appropriate.<br />
The best example of this is <strong>Oracle</strong>’s own text index. This index is used to provide keyword<br />
searching on large text items. You may create a simple text index like this:<br />
ops$tkyte@ORA10G> create index myindex on mytable(docs)<br />
2 indextype is ctxsys.context<br />
3 /<br />
Index created.<br />
<strong>and</strong> then use the text operators the creators of that index introduced into the SQL language:<br />
select * from mytable where contains( docs, 'some words' ) > 0;<br />
It will even respond to comm<strong>and</strong>s such as the following:<br />
ops$tkyte@ORA10GR1> begin<br />
2 dbms_stats.gather_index_stats( user, 'MYINDEX' );<br />
3 end;<br />
4 /<br />
PL/SQL procedure successfully completed.<br />
It will participate with the optimizer at runtime to determine the relative cost of using a<br />
text index over some other index or a full scan. The interesting thing about all of this is that<br />
you or I could have developed this index. The implementation of the text index was done<br />
without “inside kernel knowledge.” It was done using the dedicated, documented, <strong>and</strong><br />
exposed API. The <strong>Oracle</strong> database kernel is not aware of how the text index is stored (the APIs<br />
store it in many physical database tables per index created). <strong>Oracle</strong> is not aware of the processing<br />
that takes place when a new row is inserted. <strong>Oracle</strong> text is really an application built<br />
on top of the database, but in a wholly integrated fashion. To you <strong>and</strong> me, it looks just like any<br />
other <strong>Oracle</strong> database kernel function, but it is not.<br />
I personally have not found the need to go <strong>and</strong> build a new exotic type of index structure.<br />
I see this particular feature as being of use mostly to third-party solution providers that have<br />
innovative indexing techniques.<br />
I think the most interesting thing about application domain indexes is that they allow<br />
others to supply new indexing technology I can use in my applications. Most people will never<br />
make use of this particular API to build a new index type, but most of us will use the end<br />
results. Virtually every application I work on seems to have some text associated with it, XML<br />
to be dealt with, or images to be stored <strong>and</strong> categorized. The interMedia set of functionality,<br />
implemented using the Application Domain Indexing feature, provides these capabilities. As<br />
time passes, the set of available index types grows. We’ll take a more in-depth look at the text<br />
index in a subsequent chapter.