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.

244<br />

CHAPTER 7 ■ CONCURRENCY AND MULTI-VERSIONING<br />

An Explanation for Higher Than Expected I/O on Hot Tables<br />

Another situation where it is vital that you underst<strong>and</strong> read consistency <strong>and</strong> multi-versioning<br />

is when you are faced with a query that in production, under a heavy load, uses many more<br />

I/Os than you observe in your test or development systems, <strong>and</strong> you have no way to account<br />

for it. You review the I/O performed by the query <strong>and</strong> note that it is much higher than you<br />

have ever seen—much higher than seems possible. You restore the production instance on<br />

test <strong>and</strong> discover that the I/O is way down. But in production it is still very high (but seems to<br />

vary: sometimes it is high, sometimes it is low, <strong>and</strong> sometimes it is in the middle). The reason,<br />

as we’ll see, is that in your test system, in isolation, you do not have to undo other transactions’<br />

changes. In production, however, when you read a given block, you might have to undo<br />

(roll back) the changes of many transactions, <strong>and</strong> each rollback could involve I/O to retrieve<br />

the undo <strong>and</strong> apply it.<br />

This is probably a query against a table that has many concurrent modifications taking<br />

place—you are seeing the reads to the undo segment taking place, the work that <strong>Oracle</strong> is<br />

performing to restore the block back the way it was when your query began. You can see the<br />

effects of this easily in a single session, just to underst<strong>and</strong> what is happening. We’ll start with<br />

a very small table:<br />

ops$tkyte@ORA10GR1> create table t ( x int );<br />

Table created.<br />

ops$tkyte@ORA10GR1> insert into t values ( 1 );<br />

1 row created.<br />

ops$tkyte@ORA10GR1> exec dbms_stats.gather_table_stats( user, 'T' );<br />

PL/SQL procedure successfully completed.<br />

ops$tkyte@ORA10GR1> select * from t;<br />

X<br />

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

1<br />

Now we’ll set our session to use the SERIALIZABLE isolation level, so that no matter how<br />

many times we run a query in our session, the results will be “as of” that transaction’s start<br />

time:<br />

ops$tkyte@ORA10GR1> alter session set isolation_level=serializable;<br />

Session altered.<br />

Now, we’ll query that small table <strong>and</strong> observe the amount of I/O performed:<br />

ops$tkyte@ORA10GR1> set autotrace on statistics<br />

ops$tkyte@ORA10GR1> select * from t;<br />

X<br />

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

1

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

Saved successfully!

Ooh no, something went wrong!