Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 10 ■ DATABASE TABLES 351 INITRANS and MAXTRANS Each block in a segment has a block header. Part of this block header is a transaction table. Entries will be made in the transaction table to describe which transactions have what rows/elements on the block locked. The initial size of this transaction table is specified by the INITRANS setting for the object. For tables, this defaults to 2 (indexes default to 2). This transaction table will grow dynamically as needed up to MAXTRANS entries in size (given sufficient free space on the block, that is). Each allocated transaction entry consumes 23 to 24 bytes of storage in the block header. Note that as of Oracle 10g, MAXTRANS is ignored—all segments have a MAXTRANS of 255. Heap Organized Tables A heap organized table is probably used 99 percent (or more) of the time in applications, although that might change over time with the advent of IOTs, since they can themselves be indexed. A heap organized table is the type of table you get by default when you issue the CREATE TABLE statement. If you want any other type of table structure, you need to specify that in the CREATE statement itself. A heap is a classic data structure studied in computer science. It is basically a big area of space, disk, or memory (disk in the case of a database table, of course), which is managed in an apparently random fashion. Data will be placed where it fits best, rather than in any specific sort of order. Many people expect data to come back out of a table in the same order it was put into it, but with a heap, this is definitely not assured. In fact, rather the opposite is guaranteed: the rows will come out in a wholly unpredictable order. This is quite easy to demonstrate. In this example, I will set up a table such that in my database I can fit one full row per block (I am using an 8KB blocksize). You do not need to have the case where you only have one row per block—I am just taking advantage of that to demonstrate a predictable sequence of events. The following sort of behavior (that rows have no order) will be observed on tables of all sizes, in databases with any blocksize: ops$tkyte@ORA10GR1> create table t 2 ( a int, 3 b varchar2(4000) default rpad('*',4000,'*'), 4 c varchar2(3000) default rpad('*',3000,'*') 5 ) 6 / Table created. ops$tkyte@ORA10GR1> insert into t (a) values ( 1); 1 row created. ops$tkyte@ORA10GR1> insert into t (a) values ( 2); 1 row created. ops$tkyte@ORA10GR1> insert into t (a) values ( 3); 1 row created.
352 CHAPTER 10 ■ DATABASE TABLES ops$tkyte@ORA10GR1> delete from t where a = 2 ; 1 row deleted. ops$tkyte@ORA10GR1> insert into t (a) values ( 4); 1 row created. ops$tkyte@ORA10GR1> select a from t; A ---------- 1 4 3 Adjust columns B and C to be appropriate for your blocksize if you would like to reproduce this. For example, if you have a 2KB blocksize, you do not need column C, and column B should be a VARCHAR2(1500) with a default of 1,500 asterisks. Since data is managed in a heap in a table like this, as space becomes available, it will be reused. ■Note When using ASSM or MSSM, you’ll find rows end up in “different places.” The underlying space management routines are very different, and the same operations executed against a table in ASSM and MSSM may well result in different physical order. The data will logically be the same, but it will be stored in different ways. A full scan of the table will retrieve the data as it hits it, never in the order of insertion. This is a key concept to understand about database tables: in general, they are inherently unordered collections of data. You should also note that I do not need to use a DELETE in order to observe this effect; I could achieve the same results using only INSERTs. If I insert a small row, followed by a very large row that will not fit on the block with the small row, and then a small row again, I may very well observe that the rows come out by default in the order “small row, small row, large row.” They will not be retrieved in the order of insertion. Oracle will place the data where it fits, not in any order by date or transaction. If your query needs to retrieve data in order of insertion, you must add a column to the table that you can use to order the data when retrieving it. That column could be a number column, for example, maintained with an increasing sequence (using the Oracle SEQUENCE object). You could then approximate the insertion order using a SELECT that did an ORDER BY on this column. It will be an approximation because the row with sequence number 55 may very well have committed before the row with sequence 54, therefore it was officially “first” in the database. You should think of a heap organized table as a big unordered collection of rows. These rows will come out in a seemingly random order, and depending on other options being used (parallel query, different optimizer modes, and so on), they may come out in a different order with the same query. Do not ever count on the order of rows from a query unless you have an ORDER BY statement on your query!
- Page 345 and 346: 300 CHAPTER 9 ■ REDO AND UNDO Inv
- Page 347 and 348: 302 CHAPTER 9 ■ REDO AND UNDO The
- Page 349 and 350: 304 CHAPTER 9 ■ REDO AND UNDO 41
- Page 351 and 352: 306 CHAPTER 9 ■ REDO AND UNDO ins
- Page 353 and 354: 308 CHAPTER 9 ■ REDO AND UNDO So,
- Page 355 and 356: 310 CHAPTER 9 ■ REDO AND UNDO ops
- Page 357 and 358: 312 CHAPTER 9 ■ REDO AND UNDO ops
- Page 359 and 360: 314 CHAPTER 9 ■ REDO AND UNDO •
- Page 361 and 362: 316 CHAPTER 9 ■ REDO AND UNDO ...
- Page 363 and 364: 318 CHAPTER 9 ■ REDO AND UNDO •
- Page 365 and 366: 320 CHAPTER 9 ■ REDO AND UNDO bac
- Page 367 and 368: 322 CHAPTER 9 ■ REDO AND UNDO As
- Page 369 and 370: 324 CHAPTER 9 ■ REDO AND UNDO ops
- Page 371 and 372: 326 CHAPTER 9 ■ REDO AND UNDO wil
- Page 373 and 374: 328 CHAPTER 9 ■ REDO AND UNDO Thi
- Page 375 and 376: 330 CHAPTER 9 ■ REDO AND UNDO ops
- Page 377 and 378: 332 CHAPTER 9 ■ REDO AND UNDO Whe
- Page 379 and 380: 334 CHAPTER 9 ■ REDO AND UNDO Tha
- Page 381 and 382: 336 CHAPTER 9 ■ REDO AND UNDO tou
- Page 383 and 384: 338 CHAPTER 10 ■ DATABASE TABLES
- Page 385 and 386: 340 CHAPTER 10 ■ DATABASE TABLES
- Page 387 and 388: 342 CHAPTER 10 ■ DATABASE TABLES
- Page 389 and 390: 344 CHAPTER 10 ■ DATABASE TABLES
- Page 391 and 392: 346 CHAPTER 10 ■ DATABASE TABLES
- Page 393 and 394: 348 CHAPTER 10 ■ DATABASE TABLES
- Page 395: 350 CHAPTER 10 ■ DATABASE TABLES
- Page 399 and 400: 354 CHAPTER 10 ■ DATABASE TABLES
- Page 401 and 402: 356 CHAPTER 10 ■ DATABASE TABLES
- Page 403 and 404: 358 CHAPTER 10 ■ DATABASE TABLES
- Page 405 and 406: 360 CHAPTER 10 ■ DATABASE TABLES
- Page 407 and 408: 362 CHAPTER 10 ■ DATABASE TABLES
- Page 409 and 410: 364 CHAPTER 10 ■ DATABASE TABLES
- Page 411 and 412: 366 CHAPTER 10 ■ DATABASE TABLES
- Page 413 and 414: 368 CHAPTER 10 ■ DATABASE TABLES
- Page 415 and 416: 370 CHAPTER 10 ■ DATABASE TABLES
- Page 417 and 418: 372 CHAPTER 10 ■ DATABASE TABLES
- Page 419 and 420: 374 CHAPTER 10 ■ DATABASE TABLES
- Page 421 and 422: 376 CHAPTER 10 ■ DATABASE TABLES
- Page 423 and 424: 378 CHAPTER 10 ■ DATABASE TABLES
- Page 425 and 426: 380 CHAPTER 10 ■ DATABASE TABLES
- Page 427 and 428: 382 CHAPTER 10 ■ DATABASE TABLES
- Page 429 and 430: 384 CHAPTER 10 ■ DATABASE TABLES
- Page 431 and 432: 386 CHAPTER 10 ■ DATABASE TABLES
- Page 433 and 434: 388 CHAPTER 10 ■ DATABASE TABLES
- Page 435 and 436: 390 CHAPTER 10 ■ DATABASE TABLES
- Page 437 and 438: 392 CHAPTER 10 ■ DATABASE TABLES
- Page 439 and 440: 394 CHAPTER 10 ■ DATABASE TABLES
- Page 441 and 442: 396 CHAPTER 10 ■ DATABASE TABLES
- Page 443 and 444: 398 CHAPTER 10 ■ DATABASE TABLES
- Page 445 and 446: 400 CHAPTER 10 ■ DATABASE TABLES
CHAPTER 10 ■ DATABASE TABLES 351<br />
INITRANS <strong>and</strong> MAXTRANS<br />
Each block in a segment has a block header. Part of this block header is a transaction table.<br />
Entries will be made in the transaction table to describe which transactions have what<br />
rows/elements on the block locked. The initial size of this transaction table is specified by the<br />
INITRANS setting for the object. For tables, this defaults to 2 (indexes default to 2). This transaction<br />
table will grow dynamically as needed up to MAXTRANS entries in size (given sufficient free<br />
space on the block, that is). Each allocated transaction entry consumes 23 to 24 bytes of storage<br />
in the block header. Note that as of <strong>Oracle</strong> 10g, MAXTRANS is ignored—all segments have a<br />
MAXTRANS of 255.<br />
Heap Organized Tables<br />
A heap organized table is probably used 99 percent (or more) of the time in applications,<br />
although that might change over time with the advent of IOTs, since they can themselves be<br />
indexed. A heap organized table is the type of table you get by default when you issue the<br />
CREATE TABLE statement. If you want any other type of table structure, you need to specify<br />
that in the CREATE statement itself.<br />
A heap is a classic data structure studied in computer science. It is basically a big area of<br />
space, disk, or memory (disk in the case of a database table, of course), which is managed in<br />
an apparently r<strong>and</strong>om fashion. Data will be placed where it fits best, rather than in any specific<br />
sort of order. Many people expect data to come back out of a table in the same order it<br />
was put into it, but with a heap, this is definitely not assured. In fact, rather the opposite is<br />
guaranteed: the rows will come out in a wholly unpredictable order. This is quite easy to<br />
demonstrate.<br />
In this example, I will set up a table such that in my database I can fit one full row per<br />
block (I am using an 8KB blocksize). You do not need to have the case where you only have<br />
one row per block—I am just taking advantage of that to demonstrate a predictable sequence<br />
of events. The following sort of behavior (that rows have no order) will be observed on tables of<br />
all sizes, in databases with any blocksize:<br />
ops$tkyte@ORA10GR1> create table t<br />
2 ( a int,<br />
3 b varchar2(4000) default rpad('*',4000,'*'),<br />
4 c varchar2(3000) default rpad('*',3000,'*')<br />
5 )<br />
6 /<br />
Table created.<br />
ops$tkyte@ORA10GR1> insert into t (a) values ( 1);<br />
1 row created.<br />
ops$tkyte@ORA10GR1> insert into t (a) values ( 2);<br />
1 row created.<br />
ops$tkyte@ORA10GR1> insert into t (a) values ( 3);<br />
1 row created.