【实验室-技术报道】两者之间的区别 行连接是指一个行存储在多个块中的情况因为一个该行的长度超过了一个块的可用空间大小 行迁移是指一个数据行不适合放入当前块而被重新定位到另一个块但在原始块中保留一个指针原始块中的指针是必需的因为索引的rowid项仍然指向原始位置 行连接通常与行的长度和oracle数据库块中的大小有关而行迁移通常是当一个更新操作的长度增加且又要保持该行在同一块中而该块又缺少可用空间时产生的问题oracle在决定行连接之前先试图进行行迁移 检查是否存在行迁移或是连接 ()ANALYZE TABLE order_hist LIST CHAINED ROWS; ()SELECT * FROM CHAINED_ROWS WHERE TABLE_NAME = ORDER_HIST; OWNER_NAME TABLE_NAME CLUST HEAD_ROWID TIMESTAMP SCOTT ORDER_HIST AAAAluAAHAAAAAAAA MAR SCOTT ORDER_HIST AAAAluAAHAAAAAAAB MAR SCOTT ORDER_HIST AAAAluAAHAAAAAAAC MAR 贴个document i里面的资料说得比较详细: Listing Chained Rows of Tables and Clusters You can look at the chained and migrated rows of a table or cluster using the ANALYZE statement with the LIST CHAINED ROWS clause The results of this statement are stored in a specified table created explicitly to accept the information returned by the LIST CHAINED ROWS clause These results are useful in determining whether you have enough room for updates to rows For example this information can show whether PCTFREE is set appropriately for the table or cluster Creating a CHAINED_ROWS Table To create the table to accept data returned by an ANALYZE LIST CHAINED ROWS statement execute the UTLCHAINSQL or UTLCHNSQL scrīpt These scrīpts are provided by Oracle They create a table named CHAINED_ROWS in the schema of the user submitting the scrīpt Note: Your choice of scrīpt to execute for creating the CHAINED_ROWS table is dependent upon the compatibility level of your database and the type of table you are analyzing See the Oraclei SQL Reference for more information After a CHAINED_ROWS table is created you specify it in the INTO clause of the ANALYZE statement For example the following statement inserts rows containing information about the chained rows in the emp_dept cluster into the CHAINED_ROWS table: ANALYZE CLUSTER emp_dept LIST CHAINED ROWS INTO CHAINED_ROWS; See Also: Oraclei Database Reference for a descrīption of the CHAINED_ROWS table Eliminating Migrated or Chained Rows in a Table You can use the information in the CHAINED_ROWS table to reduce or eliminate migrated and chained rows in an existing table Use the following procedure Use the ANALYZE statement to collect information about migrated and chained rows ANALYZE TABLE order_hist LIST CHAINED ROWS; Query the output table: SELECT * FROM CHAINED_ROWS WHERE TABLE_NAME = ORDER_HIST; OWNER_NAME TABLE_NAME CLUST HEAD_ROWID TIMESTAMP SCOTT ORDER_HIST AAAAluAAHAAAAAAAA MAR SCOTT ORDER_HIST AAAAluAAHAAAAAAAB MAR SCOTT ORDER_HIST AAAAluAAHAAAAAAAC MAR The output lists all rows that are either migrated or chained If the output table shows that you have many migrated or chained rows then you can eliminate migrated rows by continuing through the following steps: Create an intermediate table with the same columns as the existing table to hold the migrated and chained rows: CREATE TABLE int_order_hist AS SELECT * FROM order_hist WHERE ROWID IN (SELECT HEAD_ROWID FROM CHAINED_ROWS WHERE TABLE_NAME = ORDER_HIST); Delete the migrated and chained rows from the existing table: DELETE FROM order_hist WHERE ROWID IN (SELECT HEAD_ROWID FROM CHAINED_ROWS WHERE TABLE_NAME = ORDER_HIST); Insert the rows of the intermediate table into the existing table: INSERT INTO order_hist SELECT * FROM int_order_hist; Drop the intermediate table: DROP TABLE int_order_history; Delete the information collected in step from the output table: DELETE FROM CHAINED_ROWS WHERE TABLE_NAME = ORDER_HIST; Use the ANALYZE statement again and query the output table Any rows that appear in the output table are chained You can eliminate chained rows only by increasing your data block size It might not be possible to avoid chaining in all situations Chaining is often unavoidable with tables that have a LONG column or long CHAR or VARCHAR columns 配置数据存储 数据库管理员面对的一个最常见的问题就是处理数据库对象的碎片碎片浪费空间导致性能问题并给数据库对象的管理带来更大的困难事实上数据库碎片是许多问题而不是一个问题包括分裂成碎片的数据库对象分裂成碎片的表空间连接行和转移行 数据库碎片通常是行被插入修改和删除以及对象被建立和删除的结果 分裂成碎片的表空间 表空间变成碎片是由于错误以及表空间中的数据库对象的无计划撤销和重建造成的 表空间碎片会导致下面的问题 ◆表空间中的空间被分离且不能有效地使用 ◆在需要重建分裂成碎片的对象会导致管理问题 避免数据字典的碎片 数据字典是放在SYSTEM表空间中的所以就需要将用户的默认表空间和/或临时表空间更改为非SYSTEM表空间语法如下 ALTER USER username DEFAULT USERS TEMPORARY TEMP; 处理分裂成碎片的表空间 处理表空间碎片的最好方法是避免它如果面临着整理分裂成碎片的表空间最简单的方法是在表空间中导出损坏了的对象删除该对象再把他们导入回来 要避免碎片有以下几种方法 把对象用相似的空间和增长特性聚合在一起 如果可能把它们的区间设成相同的容量这样所有的对象可以共享释放或者从删除对象中回收的区间 使每个段的PCTINCREASE保持为 聚集可用空间的技术 可用空间的聚集是通过将多个邻接的可用区变为一个较大的可用区来排除蜂窝式可用空间碎片的一个过程 以下技术可用来聚集可用空间 方法直接聚集(使用此方法定期在有碎片的表空间中聚集可用空间) 可以使用ALTER TABLESPACE COALESCE命令 方法后台SMON聚集(应避免使用此方法) 如果一个表空间的PCTINCREASE数据存储参数的值大于零则后台实例进程SMON将担当间接聚集该表空间的可用区的任务避免使用的理由 首先PCTINCREASE设为非零值将导致空间碎块的增加 其次它引起SMON的不必要的性能开销 再次SMON本身在聚集可用空间方面效率并不高 如果想要一个自动的过程可以建立一个命令脚本通过计划任务来执行 方法利用时间聚集空间(已过时) 方法请求式聚集(由Oracle服务器内部使用) 查找接近MAXEXTENTS值的对象 段及其区的信息可以从数据字典视图DBA_SEGMENTS和DBA_EXTENTS中找到 可以使用导出和导入实用程序将分成大量小区的对象重组到一个单独的大区中如果遍布在该数据库中的大量的对象都受到影响可以使用全数据库重组功能来重新组织整个数据库的空间并重新创建每个表或索引到单独的区中 在Oraclei中ALTER TABLE命令的MOVE通过将为分区的表的数据重新定位到一个新的段中并修改它的存储性来整理表的碎片 对象碎片 对象碎片会导致下面的问题 对数据库额外的读调用会导致响应时间增加 由于在表和索引块中的自由空间空洞导致空间的浪费 读性能下降因为数据不再被紧紧地排在一起物理磁盘驱动器必须从一个必须要的大的磁盘表面区域中搜寻和读数据 行转移 行转移在对行的修改引起行的长度比块中可利用空间大时发生这时会在原来的块中存放一个指针指向新的块但是这样存在两个问题 Oracle每次必须执行至少一次额外的输入/输出读来获取转移的行 Oracle也必须和行数据一起存储额外的指针来共给行转移机制 行连接 行连接在一个行太长以至于不能放入任何一个数据块时发生这导致该行被存储在一个或多个数据块的链中行连接经常伴随着包含LONGLONGRAW或者LOB数据类型的大行发生 使行连接和行迁移最小化 通常一行应该完全安放在一个单一的Oracle数据块中行连接和行迁移是两种异常情况即一行与多个数据块有关当一行太大以致于不能适合任何数据块时就发生行连接 行连接和行迁移都是不希望的情形应尽量避免由于在多个数据块中分布数据存储的行连接和行迁移将导致更大的I/O开销从而降低性能 消除连接和转移的行 通过执行下面的步骤消除所有转移行 ()使用如下的SQL语句建立一个临时表来保存转移行 CREATE TABLE temp_emp as SELECT * FROM emp WHERE rowed in (SELECT rowed FROM chained_rows WHERE table_name=EMP) ()从主表中删除前一语句存储的行 DELETE FROM emp WHERE rowed_in (SELECT head_rowed FROM chained_rows WHERE table_name=EMP) ()从临时表中插入行 INSERT INTO emp SELECT * FROM temp_emp; 这种方法的缺点 表中的许多自由空间可能永远都没用过这取决于PCTUSED的设置因此空间被浪费了 当这个表通过全表扫描被读取时因为必须读非常大量的块所以可能会损失一些性能 在尽力避免行转移时确定PCTFREE的值很重要 行连接是非常难调整的唯一的解决办法是缩短表的行长或者增加数据块的大小选择迁移中方法通常需要对表结构进行重新设计但是后一种方法需要导出整个数据库重新创建然后全部导入这两种方法都不是很吸引人但是如果一个表中的连接行引起了性能问题那么就必须使用它们 行连接/行迁移的技巧 行连接和行迁移的技巧包括如下方面 行连接一旦出现只要不用较大的数据块尺寸重建数据库就不能纠正 处理行连接的最好的方法就是防止它的出现 已开始就用大数据块尺寸创建数据库将有助于防止行连接只要最大尺寸的行不超过该数据块的大小就行数据块的大小对数据库性能有显着的影响应该根据各种情形来取定 与行连接不同行迁移更容易防止和产生 经历过繁重更新活动的数据段最容易产生行迁移 为STORAGE子句的参数PCTFREE指定的值对行迁移有很大的影响正确地设置该参数可以防止或至少可以使行迁移最小化 使用ANALYZE命令方法或通过查询V$SYSSTAT视图可以经常检查更新活动频繁的表以便及时发现行迁移 避免区出超错误 段能够得到的区的最大数由MAXEXTENTS数据存储参数决定如果段得到了所允许的区的最大值当Oracle试图再分配区时会返回错误有两种方法可以主动防止区错误 将对象的MAXEXTENTS设置为UNLIMITED如果空间允许的话应为INITIAL和NEXT考虑大一点的估计值以防止对象由于获得过多的小区而产生碎片 如果MAXEXTENTS不设为UNLIMITED则应定期检查接近最大区数量的段可以从DBA_SEGMENTS视图中找到对于接近其MAXEXTENTS限制值的对象可以随意选择使用以下任一个或所有操作(a)增加该段的MAXEXTENTS(b)增加NEXT区的大小(c)将该对象重组到一个单独的区中 避免空间出超错误 当由于表空间的可用空间匮乏而Oracle不能将一个区分配给对象时会出现空间的出超(outofspace)错误采用以下一种或两种方法可以防止这些错误 将AUTOEXTEND设为ON 进行可用空间的定期检查 怎样定义表的大小 SQL函数VSIZE返回以字节为单位的列值的大小VSIZE对于定义表的大小是相当有用的 VSIZE可用来确定以下内容 表中所有行的大小 以字节为单位的平均行大小 以字节为单位的最大的行尺寸 下面介绍完成该项任务的技术 计算总的大小 使用VSIZE与其它的SQL函数可计算表中所有行的总大小计算表大小的选择语句的一般形式是 SELECT SUM(NVL(VSIZE(col)))+ SUM(NVL(VSIZE(col)))+ … + SUM(NVL(VSIZE(coln))) FROM table; NVL函数用于将NULL值替换为 计算平均行尺寸 将SUM改为AVG可以计算平均行尺寸 计算最大行尺寸 将SUM改为MAX可以获得表的最大行的尺寸 怎样确定PCTFREE的最佳值 PCTFREE指定Oracle为容纳当前存储行在更新时的扩展而在数据块中保留的可用空间数量如果PCTFREE设得值很低就有出现行迁移的危险如果设得过高可能会浪费空间并由于每空中的行很少而导致较低的块密度 用经验方法估计PCTFREE 可考虑对以下情况的表设置较高的PCTFREE值(a)包含有今后要被更新的空列的记录(b)包含有小尺寸的但今后可能被更新为较大值的列 利用公式计算PCTFREE |