I pre-ordered this book in May, having previously read the two previous editions of this book (“Expert One-On-One Oracle” and “Expert Oracle Database Architecture: 9i and 10g Programming Techniques and Solutions”) cover to cover. Now that I have had an opportunity to fully read this edition, I now realize that the first edition of this book subconsciously set the standards that I expected of all other Oracle Database books I have subsequently purchased. The latest edition is now among my five favorite Oracle Database books, sharing the top five ranking with “Cost-Based Oracle Fundamentals”, “Troubleshooting Oracle Performance”, and “Optimizing Oracle Performance”.

The author of this book is a Vice President at Oracle Corporation, and is well known for his asktom.oracle.com website, articles in Oracle’s magazine, forum/Usenet postings, and presentations. The author recently revised the Oracle Concepts Guide, which is part of the Oracle Database 11.2 documentation library. Slightly off topic: It might be notable that a book written by a VP at Oracle Corporation is not published by Oracle Press. Oracle Press is a marketing label used by McGraw Hill to market its line of Oracle books – the books are not formally written by Oracle Corporation nor are they formally tech edited by Oracle Corporation, although some employees of Oracle Corporation have used McGraw Hill as a publishing company. At least for me, for several years the “Officially Authorized Oracle Press” logo on books published by McGraw Hill seemed to be an endorsement of the books by Oracle Corporation, but that is not the case, as was clarified by one of the threads on the AskTom site (ReferenceReference2).

The book contents are very well organized, allowing the reader to continually build on previously introduced concepts. Many forward and backward references in the book are provided – “see the section a1 in chapter n for additional information”. It is surprising just how much new content is included in this edition of the book – this book reads as though it were written specifically for Oracle Database 11g R2 with exceptions in behavior mentioned for older Oracle Database releases. Even if you have read one of the older releases of the book, I do not recommend just jumping into one of the chapters using either the table of contents or the index at the back of the book. Start at the beginning of the book and finish at the end of the book. The author introduces very useful bits of information in the chapters that are not specific to the chapter title, and do not appear in the table of contents or the index at the back of the book. Just a couple of examples of useful information that will be missed (especially if you only read the first half of the book):

Page 487: Using DBMS_SPACE.FREEBLOCKS to determine the number of index blocks in the index freelist.

Page 512: Using the VSIZE function to indicate how much storage space a column value requires.

Page 513: Warns of a calculation error (that is not a bug) when adding the floating point numbers 0.3 and 0.1 – the result is not 0.4.

Page 646: Using DBMS_STATS.SET_TABLE_STATS to simulate a large table in order to determine how data volume changes will impact the execution plan generated by the optimizer.

Page 656: Using the NTILE analytic function to break a rowset into equally sized groups of rows.

Page 687: Starting with Oracle 9i it is possible to insert into one or more tables using complex WHEN conditions.

Page 739: Encrypting a column in a table may cause significant changes to the execution plans that specify that column in join or filtering conditions.

Page 740: Index range scans are not possible with indexes created for encrypted columns.

The author uses an odd, yet very helpful teaching method throughout the book. Break something, with the assumption that you are reading the chapter because something is already broken, and then show you how to fix the problem and ultimately avoid the problem in the future. Unfortunately, the index at the back of the book only contains a small handful of these problem-solution cases – another reason to read the whole book and take good notes. A list of the errors covered in the book as teachable moments follows:

Notes at the front of the book show how to quickly install Statspack, change AUTOTRACE settings, permanently configure the SQL*Plus environment, and the requirements for the Runstats, Mystat, Show_Space, and Big_Table scripts that are used later in the book.

Provides a warning not to use bitmap indexes on columns just because the columns have low cardinality, for example a column named PROCESSED that has either a value of Y or N, without first considering concurrency – how will the column be used and updated.

Pages 17 through 21 demonstrate SQL injection when bind variables are not used in an example that most people probably would not consider as a threat – the SQL injection was accomplished by simply changing the NLS_DATE_FORMAT (Reference).

Page 72 warns against setting undocumented parameters: “Use undocumented parameters only at the request of Oracle support. Their use can be damaging to a database, and their implementation can – and will – change from release to release.” This is a warning that should be included in every book before the first mention of hidden parameters.

The book provides a detailed list and description of the functionality provided by Oracle’s background processes.

Demonstrates how to build test cases to verify performance/scalability issues.

Pages 262-265 provide a very detailed demonstration of transactions automatically restarting. This behavior might cause, for example, before update triggers to fire more than once, various problems with PL/SQL variables, autonomous transactions, and various PL/SQL packages (UTL_FILE, UTL_SMTP, UTL_HTTP, etc.).

Excellent section on the topic of index myths, one of which had its roots in Oracle Database 5.

Excellent six case summary of why an index may not have been used.

Shows a lot of examples of practical SQL and PL/SQL in test cases, which is extremely helpful for people trying to learn either SQL or PL/SQL. The test cases frequently include TKPROF output.

The book includes a nice analogy of Oracle Database’s parallel execution option by comparing that feature with writing either a short or long report – coordinating the writing of a small report could take longer than simply writing the report without assistance.

The chapter showing the use of external data includes examples with SQLLOADER, external tables, flat files, and Data Pump unload (used to write out the contents of a table to allow that table’s rows to be used in another database).

The book almost always lists the first Oracle release version that offered a feature when that feature is introduced in the book.

Typically indicates when syntax introduced in the book is operating system dependent. For example, on page 682 “ls –l” is specified for Unix/Linux and “dir /q /n” for Windows.

The downloadable source code library seems to be complete, making it easy for readers to reproduce the tests that are found in the book.

Not everything about the book is perfect. The errata page for the book currently lists a problem where the author used the word “be” too many times in a sentence. What else needs a little fine tuning, is not quite right, or is simply incorrect? The following are my observations about the book:

The book frequently seems to assume that a fully optioned version of the Enterprise Edition of Oracle is used by all of the readers of the book, which may set the readers up for false hope in solving certain problems, or implementing solutions that cannot be used in production environments (the chapters discussing bitmap indexes, partitioning, and parallel execution are exceptions, where the requirements are stated):
— Advanced Queuing on page 10
— SQL Profiles on page 11
— FLASHBACK on page 26
— Fine-grained access control on page 46
— Index key compression on page 407
— Chapter on the topic of Data Encryption does not mention what capabilities are available for the Standard Edition, Enterprise Edition, or the Enterprise Edition with the Oracle Advanced Security Option.

Page xxxvi describes running the utlxplan script as the user SYSTEM. Running this script should not be necessary starting with Oracle Database 9i (Reference).

Chapter 1 seems to be a little loose with terminology, specifically with the terms “database” and “Oracle”. These chapters were probably intentionally written as such to help introduce the reader to the world of Oracle Database. The first couple of pages of the second chapter provide a definition of “database” and “instance”.

Page 109 typing error: “Normally, on UNIX/Linux, this group will be DBA by default, and OSDBA on Windows. That group is ‘special,’ in that any user in that group can connect to Oracle ‘as SYSDBA’ without specifying a username or password.” On Windows the group name is ora_dba, not OSDBA – the same error is found in the previous edition of the book (Reference).

Page 131 behavior change: “A serial (nonparallel query) session will use a small percentage of the PGA_AGGREGATE_TARGET, typically about 5 percent or less. So, if you’ve set the PGA_AGGREGATE_TARGET to 100MB, you’d expect to use no more than about 5MB per work area (e.g., the sort or hash work area). You may well have multiple work areas in your session for multiple queries, or more than one sort or hash operation in a single query, but each work area will be about 5 percent or less of the PGA_AGGREGATE_TARGET.” It appears that this behavior changes when the OPTIMIZER_FEATURES_ENABLE parameter is set to 10.2.0.1 or greater, as evidenced by the change in the _SMM_MAX_SIZE parameter as found in a 10053 trace file or a query of X$KSPPSV and X$KSPPI (ReferenceReference2).

Page 220 join error: The self-join of V$LOCK probably should have also joined on the TYPE column in addition to the ID1 and ID2 column. Additionally, the BLOCK column could potentially have a value of 2, rather than 1 in a RAC environment (Reference).

Page 335 typing error: shows the view name V$UNDOSTATUNDOSTAT, should be V$UNDOSTAT.

Page 419 suggested use of a deprecated feature: Shows using the exp command with Oracle Database 11.2.0.1 to create a people.sql file containing a CREATE TABLE command for an object based table. Page 116 states the following “Export [exp] is officially deprecated with Oracle Database 11g Release 2. It is supplied only for use with legacy database structures.”

Some of the autotrace generated execution plans do not conform to the DBMS_XPLAN style execution plans that are automatically generated as of Oracle Database 10g R2, even though it appears that the author was connected to Oracle Database 11g R2. Examples include the two execution plans on page 480.

The SQL*Plus prompts are atypical (not “SQL>”) as displayed in the book – while it might be helpful to show which database the SQL*Plus session is connected to, it makes it hard to read some of the code samples that span more than a single line.

The problems found in the book are absolutely minor in comparison to the value of the information provided in the book. Yes, it is probably harsh to be judged by the standards set in the previous edition of the book. This edition update was certainly not a five hour task, and probably was not a five month task either. I suspect that this edition has been in development for most of the last five years, since the publication of the previous edition. If you have read the previous editions of this book, set those books aside and start reading from the beginning of this edition – you will not be disappointed.

(Section added December 13, 2010): Related blog articles that discuss the contents of this book:

Hints for Posting Code Sections in Comments

********************
When the spacing of text in a comment section is important for readability (execution plans, PL/SQL blocks, SQL, SQL*Plus output, etc.) please use a <pre> tag before the code section and a </pre> tag after the code section:
<pre>

SQL> SELECT
2 SYSDATE TODAY
3 FROM
4 DUAL;
TODAY
---------
01-MAR-12

</pre>
********************
When posting test case samples, it is much easier for people to reproduce the test case when the SQL*Plus line prefixes are not included - if possible, please remove those line prefixes. This:

SELECT
SYSDATE TODAY
FROM
DUAL;

Is easier to execute in a test case script than this:

SQL> SELECT
2 SYSDATE TODAY
3 FROM
4 DUAL;

********************
Greater than and Less than signs in code sections are often interpretted as HTML formatting commands. Please replace these characters in the code sections with the HTML equivalents for these characters: