Book Review: Expert Oracle Database 11g Administration

This is a huge book, which could possibly best be described as the condensed encyclopedia of Oracle databases. The book covers everything from administration to performance tuning to using SQL*Plus to installing Oracle on Linux to using RMAN. While I did not read this book cover to cover, I did page through the book looking for interesting topics to read. I did read the author’s “Expert Oracle Database 10g Administration” book cover to cover a couple years ago and was at the time very impressed with that book. There were a couple small errors in the 10g book, repeated a couple times, but I commented to a couple people that the 10g book is by far the best and most thorough Oracle reference book that I had run across. The appendix at the back of the 10g book was very effective in helping me find exactly the right topic, and usually the right syntax for just about any task. The appendix in the 11g version of the book is just about as good. It appears that the author may have rushed the job of updating the 10g book for 11g R1 as quite a few screen captures still show Oracle versions such as 10.1.0.3 and a couple other sections of the book also seem to be more specific to 10g R1 than 11g R1 (or 11g R2).

This book contains a lot of great and/or very helpful information, but while paging through the book I found a couple problems. Overlooking the problems, I would still recommend this book as a reference for Oracle 11g R1. The section on performance tuning is not my first choice for performance tuning information.

Problems found when paging through the book (I know that I probably missed several issues):

Page 90 mentions RAID 0+1 but not the more robust RAID 10.

Page 92 states “RAID 5 offers many advantages over the other levels of RAID. The traditional complaint about the `write penalty’ should be discounted because of sophisticated advances in write caches and other strategies that make RAID 5 more efficient than in the past.” Visit http://www.baarf.com/ to see the opinions of other DBAs.

Page 166 states “if you use an Oracle block size of 64KB (65,536 bytes)…” The maximum supported block size is 32KB, not 64KB, and some platforms support a maximum of a 16KB block size.

Page 171 states when suggesting the use of multiple block sizes in a single database “if you have large indexes in your database, you will need a large block size for their tablespaces.” “Oracle provides separate pools for the various block sizes, and this leads to better use of Oracle memory.” For those who have followed the multiple block size discussions over the years, it should be fairly clear that it is not a good idea to use multiple block sizes in a single database. Oracle’s documentation states that multiple block sizes are intended to be used only to support transportable tablespaces.

Page 181 states “The database writer process writes dirty blocks to disk under the following conditions… Every 3 seconds.” A check of the Oracle documentation will quickly confirm that this is not the case.

Page 182 states “Oracle further recommends that you first ensure that your system is using asynchronous I/O before deploying additional database writer processes beyond the default number – you might not need multiple database writer processes if so.” I think that I misread this several times as saying “do not enable multiple database writers unless you also plan to enable asynchronous I/O,” which would be an incorrect statement.

Page 190 states “this is why the buffer cache hit ratio, which measures the percentage of time users accessed the data they needed from the buffer cache (rather than requiring a disk read), is such an important indicator of performance of the Oracle instance.” The author provides a link on page 1161 to an article authored by Cary Millsap which discusses why a higher buffer cache hit ratio may not be ideal. This is definitely a step in the right direction regarding the buffer cache hit ratio, but it might be better to simply ignore the statistic.

Page 395 states “11.1.0 is an alternative name for Oracle Database 11g Release 2.” Oracle 11g R2 was just released on September 1, 2009 and its version is 11.2.0.1.

Page 402 correctly (according to the documentation) states that Oracle Enterprise Linux 4 and 5, as well as Red Hat Enterprise Linux are supported platforms for Oracle Database 11g, and correctly (according to the documentation) does not list Red Hat Enterprise Linux 3. Page 403 lists the required RPM packages for Red Hat Enterprise Linux 3, but ignores the supported Linux platforms.

Page 405 shows parameters that need to be set on Linux. This appears to be a direct copy of the parameters in the Oracle documentation, but the author did not include the net.core.wmem-max parameter. Note that Oracle 11.2.0.1 will require different parameters than those specified in this book, but that is not the fault of the author.

Page 452 states that the COMPATIBLE parameter may be set to “10.2 so the untested features of the new Oracle version won’t hurt your application.” I think that this is misleading at best.

Page 466 states “If you’re supporting data warehouse applications, it makes sense to have a very large DB_BLOCK_SIZE – something between 8KB and 32KB. This will improve database performance when reading huge chunks from disk.” This is not quite a correct statement, especially if the DB_FILE_MULTIBLOCK_READ_COUNT is set correctly, or not set in the case Oracle 10.2.0.1 or above is in use. 8KB is the standard block size, so I am not sure why the author groups it with the other block sizes in the very large block size group.

Page 477 states “the default value for the STATISTICS_LEVEL initialization parameter is TYPICAL. You need to use this setting if you want to use several of Oracle’s features, including Automatic Shared Memory Management.” This is an incomplete statement as a setting of ALL will also work.

Page 1055 shows the use of both CASCADE>=YES and CASCADE=>’TRUE’ with DBMS_STATS. I believe that TRUE is the correct syntax, but it should not be specified in single quotes.

Page 1067 states “subqueries perform better when you use IN rather than EXISTS.” The reality is that Oracle may very well automatically transform queries using IN syntax into queries using EXISTS syntax (or vice-versa), and may even transform both IN syntax queries and EXISTS syntax queries into standard join syntax.

Page 1074 stated that “inline stored functions can help improve the performance of your SQL statement.” The author then demonstrated this concept by converting a SQL statement with a three table equijoin accessing apparent primary and foreign keys of the tables into a SQL statement which accessed a single table and called two PL/SQL functions (per row), each of which queried one of the other two tables which were included in the original equijoin SQL statement. This approach does not seem to be a good idea given the number of additional context switches which will result, as well as the additional number of parse calls. In short, do not solve something in PL/SQL when it may be easily solved in SQL alone.

Page 1075 states “you should avoid the use of inequality and the greater than or equal to predicates, as they may also bypass indexes.” Something does not look right about that statement.

Page 1089 states “the indexes could become unbalanced in a database with a great deal of DML. It is important to rebuild such indexes regularly so queries can run faster.” Interesting suggestion – I believe that standard SELECT statements are classified as DML as they are definitely not DDL. An index cannot become unbalanced, and indexes rarely need to be rebuilt – see Richard Foote’s blog for the more details.

Page 1089 states “when you rebuild the indexes, include the COMPUTE STATISTICS statement so you don’t have to gather statistics after the rebuild.” Oracle 10g and above automatically collect statistics when building indexes, and I would assume that the same is true when rebuilding indexes.

Page 1108 states that “cpu_time is the total parse and execute time” when describing the columns found in V$SQL. It is actually the time measure in centiseconds (100th of a second) of the CPU utilization when executing the SQL statement, and probably also includes the CPU time for parsing the SQL statement, but I have not verified this.

Page 1154 provides a demonstration of finding sessions consuming a lot of CPU time. The example used the `CPU used by this session’ statistic rather than drilling through V$SYS_TIME_MODEL into V$SESS_TIME_MODEL. The example used the `CPU used by this session’ as a reason for examining parse CPU usage and recursive CPU usage. While it is good to check CPU usage of sessions, there are a couple problems with this approach. First, the `CPU used by this session’ statistic is not updated until the first fetch from a SQL statement is returned to the client. If the client was waiting for the last hour for the first row to be returned, the CPU utilization will show close to 0 seconds difference between the start of the SQL statement and the check of the `CPU used by this session’ statistic in V$SESSTAT – this is not the case for the statistics in V$SESS_TIME_MODEL, which are updated in near real-time. Second, the change (delta) in the statistic for the sessions was not determined – if one session had been connected for 120 days, it probably should have consumed more CPU time than a session connected for 30 minutes, and probably should not be investigated.

Even with the above issues, I would still recommend this book as a reference. For specific information on performance tuning, using RMAN, or installing on Linux, it might be a good idea to use a second book for deeper understanding of the process.

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: