Chained and Migrated Rows are explained in the Logical Storage Structures of the Concepts Guide.
A migrated row would be a row who's column data was completely transferred from one block to another due to an update. The original block would essentially only have a "forwarding address" stored for that row.
A chained row would have parts of its column data in multiple blocks. The original block would contain both actual column data and a forwarding address for the rest of it. (You can get rows chained to more than two blocks.)
Both are implemented the same way deep down, so they're really two aspects of the same thing.
Also note that for tables with more than 255 columns, all rows are technically chained - one "row piece" can only contain 255 column values. The chaining can happen in the same block, or with other blocks depending on space availability (and isn't particularly "bad" if all the data ends up in the same block).
The only way, as far as I know, to get accurate data on row chaining is to use:
ANALYZE TABLE your_table [partition (your_part)] LIST CHAINED ROWS
See Listing Chained Rows of Tables and Clusters.
This is potentially expensive, the whole table needs to be scanned. Statistics gathering doesn't fill the CHAIN_CNT
column of the dba_tables
view. (I think it might have at some point, but it doesn't in 11.2 at least.)
You can monitor the table fetch continued row
1 statistic (v$sysstat
) to see if a query is affected by chained or migrated rows, but I don't believe you can have that metric per-session so either you need a quiet system to measure, or the reading will be "noisy".
The Secrets of Oracle Row Chaining and Migration has interesting information about chained and migrated rows, how you measure them, and potential ways of fixing them.
As always, don't go about rebuilding tables or changing storage parameters "just because" you see chained or migrated rows. Do so only if you measure that it's actually causing you performance problems.
1 From Statistics Descriptions:
Number of times a chained or migrated row is encountered during a fetch
Retrieving rows that span more than one block increases the logical I/O by a factor that corresponds to the number of blocks than need to be accessed. Exporting and re-importing may eliminate this problem. Evaluate the settings for the storage parameters PCTFREE and PCTUSED. This problem cannot be fixed if rows are larger than database blocks (for example, if the LONG datatype is used and the rows are extremely large).
See also Table Fetch by Continued Row.
First look what other parameters are set:
CREATE pfile='pfile.txt' FROM spfile;
Maybe db_cache_size, shared_pool_size, sga_target or other memory related parameters are set to non zero? Remember that when using AMM those parameters specify minimum memory allocated for particular pool. So if sga_target is 6GB you will not be allowed to set memory_target to 4GB.
Also sum of internal variables __sga_target, __db_cache_size, etc. may be more than your specified value of 4GB.
If you see those symptoms you can cleanup pfile bounce Oracle with pfile and recreate spfile. In the same step you can also set PGA_AGGREGATE_TARGET
to zero.
STARTUP pfile='pfile.txt'
CREATE spfile from pfile='pfile.txt';
Best Answer
The docs for
sga_max_size
say:And according to Oracle document Automatic Memory Management (AMM) on 11g (Doc ID 443746.1), if you have both
sga_target
andpga_aggregate_target
unset, then:So the simplest thing to do if you want Oracle to completely control the SGA is to reset it and let the default apply:
(And restart.)
If you want AMM but would like minimum values for the SGA or the PGA (or both), do so by setting the corresponding
_target
parameter:Whatever you do, don't set the PGA or SGA target or max size to greater than the memory target. This prevents instance startup.