05.11.2015 Views

Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

442<br />

CHAPTER 11 ■ INDEXES<br />

In my database using an 8KB blocksize, these tables had the following number of total<br />

blocks apiece:<br />

ops$tkyte@ORA10G> select table_name, blocks<br />

2 from user_tables<br />

3 where table_name in ( 'COLOCATED', 'DISORGANIZED' );<br />

TABLE_NAME<br />

BLOCKS<br />

------------------------------ ----------<br />

COLOCATED 1252<br />

DISORGANIZED 1219<br />

The query against the disorganized table bears out the simple math we did earlier: we did<br />

20,000+ logical I/Os (100,000 total blocks queried <strong>and</strong> five runs of the query). We processed<br />

each <strong>and</strong> every block 20 times! On the other h<strong>and</strong>, the physically COLOCATED data took the<br />

logical I/Os way down. Here is the perfect illustration of why rules of thumb are so hard to<br />

provide—in one case, using the index works great, <strong>and</strong> in the other case it doesn’t. Consider<br />

this the next time you dump data from your production system <strong>and</strong> load it into development,<br />

as it may very well provide at least part of the answer to the question, “Why is it running differently<br />

on this machine—aren’t they identical?” They are not identical.<br />

■Note Recall from Chapter 6 that increased logical I/O is the tip of the iceberg here. Each logical I/O<br />

involves one or more latches into the buffer cache. In a multiuser/CPU situation, the CPU used by the second<br />

query would have undoubtedly gone up many times faster than the first as we spin <strong>and</strong> wait for latches. The<br />

second example query not only performs more work, but also will not scale as well as the first.<br />

THE EFFECT OF ARRAYSIZE ON LOGICAL I/O<br />

It is interesting to note the effect of the ARRAYSIZE on logical I/O performed. ARRAYSIZE is the number of<br />

rows <strong>Oracle</strong> returns to a client when they ask for the next row. The client will then buffer these rows <strong>and</strong> use<br />

them before asking the database for the next set of rows. The ARRAYSIZE may have a very material affect<br />

on the logical I/O performed by a query, resulting from the fact that if you have to access the same block over<br />

<strong>and</strong> over again across calls (across fetch calls specifically in this case) to the database, <strong>Oracle</strong> must retrieve<br />

that block again from the buffer cache. Therefore, if you ask for 100 rows from the database in a single call,<br />

<strong>Oracle</strong> might be able to fully process a database block <strong>and</strong> not need to retrieve that block again. If you ask for<br />

15 rows at a time, <strong>Oracle</strong> might well have to get the same block over <strong>and</strong> over again to retrieve the same set<br />

of rows.<br />

In the example earlier in this section, we were using SQL*Plus’s default array fetch size of 15 rows (if<br />

you divide the total rows fetched by the number of fetch calls, the result is very close to 15). If we were to<br />

compare the execution of the previous queries using 15 rows per fetch versus 100 rows per fetch, we would<br />

observe the following for the COLOCATED table:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!