Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询处理 » 查询优化与执行 » 提高查询性能

 

对插入的行的磁盘分配

下面一节将说明数据库中的行是如何存储在磁盘上的。

SQL Anywhere 会在可能的情况下连续存储行

每一个小于数据库文件页面大小的新行都始终存储在一个页上。如果现有页没有足够的空间可用于新行,SQL Anywhere 就会将该行写入新页。例如,如果新行需要 600 字节的空间,但一个被部分填充的页上只有 500 字节的可用空间,SQL Anywhere 就会将该行放在一个新页上。

为了使表页在磁盘上更为连续,SQL Anywhere 将以块的形式(每块包含八页)来分配表页。例如,当它需要分配某个页时,它将先分配八页,将要分配的页插入块中,然后用后面的七页将块填满。此外,它会使用可用页位图来查找 dbspace 中的连续页块,并通过读取 64 KB 的组和使用位图查找相关页来执行顺序扫描。这样,顺序扫描的效率就会得到提高。

SQL Anywhere 可以按任意顺序存储行

SQL Anywhere 查找页上的空间并将行按接收顺序插入其中。它会将每一行分配给某一页,但它在表上选择的位置可能与行的插入顺序不对应。例如,为了连续存储一个很长的行,数据库服务器可能需要开始一个新页。如果下一行较短,它可能适合放在前一页上的空位置。

所有表的行都未进行排序。如果行的接收或处理顺序非常重要,请在 SELECT 语句中使用 ORDER BY 子句对结果进行排序。依赖于表中行顺序的应用程序可能会不发出警告就失败。

如果您经常需要让表的行具有特定的顺序,则应在查询的 ORDER BY 子句中所指定的那些列上创建索引。

没有为 NULL 列预留空间

缺省情况下,每当 SQL Anywhere 插入一行时,它所预留的存储空间仅为存储该行在创建时所含的值所必需的空间。它不会为存储 NULL 值或容纳大小可能会增加的字段(例如文本字符串)而预留空间。

可以通过在创建表时使用 PCTFREE 选项来强制 SQL Anywhere 预留空间。有关详细信息,请参见CREATE TABLE 语句

行标识符在插入后不可变

在页上为行分配主位置之后,行就不会再从该页上移开。如果更新操作更改了该行中的某些值,导致行不能被装入为其指派的页,则行会拆分开来,额外信息将被插入到另一页。

这一特点需要特别注意,因为在插入行时,SQL Anywhere 不允许额外的空间。例如,假设您在表中插入大量的空行,然后使用 UPDATE 语句一次一列地填入值。结果将是几乎单个行中的每个值都存储在一个单独页上。为检索一行中的所有值,数据库服务器可能需要读取若干个磁盘页。这一简要操作将变得极为缓慢而且这种缓慢毫无必要。

您应该考虑在插入时用数据填充新行。插入之后,它们将具有足够的空间来保存您需要保存的数据。

数据库文件从不会缩小

当从数据库插入和删除行时,SQL Anywhere 会自动重新使用这些行占用的空间。因此,SQL Anywhere 可以将行插入先前被其它行占用的空间。

SQL Anywhere 会记录每个页上的空白空间大小。当您要求它插入新行时,它首先会搜索有关现有页空间的记录。如果它发现现有的页上有足够的空间,就会将新行放在该页上,并在必要时重组该页的内容。否则,它会开始一个新页。

如果您在一段时间内删除了几行,并且所插入的新行都比较大,以至于无法利用空白空间,则数据库中的信息就会变得非常分散。您可以重装该表,或使用 REORGANIZE TABLE 语句整理该表的碎片。

有关详细信息,请参见REORGANIZE TABLE 语句