⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch05.htm

📁 这个是sap开发语言abap的教育文档
💻 HTM
📖 第 1 页 / 共 5 页
字号:
for records from the same group. For example, if a user logs on
in English, it is highly probable that only English descriptions
will be read by that user and by other users on the same application
server. Text tables, where descriptions are stored, always have
<TT>mandt</TT> and <TT>spras</TT> (the language code) as the first
two fields. Therefore, generic buffering with <TT>n</TT> equal
to 2 is appropriate.<BR>
</BLOCKQUOTE>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=600><BLOCKQUOTE>
<B>CAUTION</B>
</BLOCKQUOTE>

</TD></TR>
<TR VALIGN=TOP><TD WIDTH=600><BLOCKQUOTE>
Each record group in the buffer requires administrative overhead. Try to have a relatively large number of records per group. With generic buffering, if you end up loading most of the rows of a table and they are loaded into many small groups, a fully buffered table will be more efficient.</BLOCKQUOTE>

</TD></TR>
</TABLE>
</CENTER>
<BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE>
During buffer synchronization, if a table is buffered generically
and a record is invalidated in the buffer, all records in the
group are invalidated. The next read of any record in that group
will cause the entire group to be reloaded.
</BLOCKQUOTE>
<H5>Single Record Buffering</H5>
<BLOCKQUOTE>
Tickmarking the Single Records check box turns on single-record
buffering. With this type of buffering, <TT>select single</TT>
picks one record into the single record buffer <TT>TABLP</TT>,
as shown in Figure 5.19. With this buffering type, records are
only buffered when the <TT>select single</TT> statement is executed.
<TT>Select/endselect</TT> does not load or read <TT>TABLP</TT>.
</BLOCKQUOTE>
<P>
<A HREF="javascript:popUp('f5-19.gif')"><B>Figure 5.19:</B> <I>With single-record buffering enabled, select
single loads records one at a time into the TABLP buffer</I>.</A>
<BLOCKQUOTE>
For example, if table <TT>ztxlfa1</TT> has a buffering type of
single records, <TT>select <I>single</I>
* from ztxlfa1 where lifnr = 'V1'</TT> causes the <TT>TABLP</TT>
buffer to be searched for record <TT>V1</TT>. If it is found there,
that copy is used. If it is not found, it is loaded into <TT>TABLP</TT>
from the database.
</BLOCKQUOTE>
<BLOCKQUOTE>
Even if a record is <I>not</I> found, an entry is <I>still</I>
made into the single record buffer. The entry indicates that record
does not exist in the database. The next time that record is requested,
the buffer can be used to resolve the request and a database access
is not necessary.
</BLOCKQUOTE>
<BLOCKQUOTE>
For example, suppose vendor <TT>X1</TT> does not exist in the
database. Executing <TT>select single * from ztxlfa1 where lifnr
= 'X1'</TT> would cause an entry to be created in the single record
buffer to indicate that record X1 does not exist in the database.
The next time vendor <TT>X1</TT> is requested, the system looks
in the buffer and discovers that it does not exist and does not
need to go to the database.
</BLOCKQUOTE>
<BLOCKQUOTE>
Single-record buffering is appropriate for very large tables in
which a small percentage of the records are read often. For single-record
buffering to work, records must be read using the <TT>select single</TT>
statement.
</BLOCKQUOTE>
<H4>Buffering Types Summarized</H4>
<BLOCKQUOTE>
In summary, there are two buffers: <TT>TABL</TT> (the generic
record buffer) and <TT>TABLP</TT> (the single record buffer).
There are also two varieties of the <TT>select</TT> statement:
<TT>select</TT> and <TT>select single</TT>. The <TT>select</TT>
statement loads <TT>TABL</TT> and the <TT>select single</TT> statement
loads <TT>TABLP</TT>.
</BLOCKQUOTE>
<BLOCKQUOTE>
When reading, <TT>select</TT> only reads <TT>TABL</TT>; it ignores
<TT>TABLP</TT>. <TT>select single</TT> reads both buffers. This
behavior is summarized in Figure 5.20. Remember that a record
can only be in one buffer at a time because a table can only have
one buffering type.
</BLOCKQUOTE>
<P>
<A HREF="javascript:popUp('f5-20.gif')"><B>Figure 5.20:</B> <I>How the select statements interact with
the buffers</I>.</A><P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=600><B>TIP</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=600>
<BLOCKQUOTE>
To clear the contents of both <TT>TABL </TT>and <TT>TABLP</TT>, type /$tab in the Command field and press the Enter key. You can use this method after you turn off buffering to clear the buffers before testing the difference in a program's performance. Note that this can slow system performance in general for up to a couple of hours until the buffers are again repopulated.
</BLOCKQUOTE>

</TD></TR>
</TABLE>
</CENTER>
<P>
<H4>Buffer Displacement</H4>

If <TT>TABLP</TT> is full and a new record needs to be loaded,
the oldest ones are thrown away to make room for it. The <I>oldest
ones</I> are the ones that have been sitting there the longest
without being accessed.<p>
In <TT>TABL</TT>, old records are not discarded when new ones
are loaded. Instead, entire tables are periodically unloaded from
the buffer. The length of time between unloads and which tables
are unloaded is determined by a caching algorithm within R/3.
This complex algorithm is based on the amount of space used by
a table in the buffer versus the number of read accesses on it
in the previous period, and also on the amount of free space available
in the buffer and the current access quality of the buffer.

<H4>Deciding Whether to Buffer</H4>

The goal in buffering is to reduce the number of database reads
and the amount of network traffic from the database to the application
servers. The following sections will list scenarios with buffering
tables that are not updated, along with buffering and indexing.

<H5>Buffering Tables That Are not Updated</H5>
<BLOCKQUOTE>
If a table is frequently accessed without being updated often,
it should be buffered. You will need to consult your Basis administrator
to find out if there is enough room in the buffer to add your
table. If there is not, and your table will be accessed often,
it might be possible to increase the amount of RAM allocated to
the buffers. Alternatively, another table accessed less frequently
than yours could be changed so that it is no longer buffered.
</BLOCKQUOTE>
<H5>Buffering and Indexes</H5>
<BLOCKQUOTE>
Records in a buffer have their own primary index built in RAM.
When records are needed, the index is used to locate them in the
buffer the same way the primary index in the database is used
to locate records in a table. However, <I>secondary</I> indexes
are <I>not</I> created in the buffer, nor are the database secondary
indexes used to access buffered data. Therefore, when coding a
<TT>select. . .where</TT> statement on a buffered table, use primary
key fields in the <TT>where</TT> clause beginning with the first
field of the primary key and using as many in sequence from the
primary key as you can. If the first field of the primary key
is missing from the <TT>where</TT> clause (not counting <TT>mandt</TT>),
a full scan of the table in the buffer will be performed. For
example, if table <TT>ztxlfa1</TT> has been fully buffered, <TT>select
* from ztxlfa1 where lifnr = 'V1'</TT> will be supported by the
buffer's primary index. <TT>Select * from ztxlfa1 where land1
= 'CA'</TT> will cause a full table scan in the buffer to occur.
</BLOCKQUOTE>
<BLOCKQUOTE>
Being unable to use secondary indexes causes a peculiar catch-22
effect if you fully buffer large tables that have secondary indexes.
Buffering such a table will cause <TT>select</TT>s on the primary
index to speed up, but it will possibly slow <TT>select</TT>s
on secondary indexes down. A <TT>select</TT> statement on a large
table (size category 1 or greater) that is fully supported by
a secondary index in the database could run slower against the
buffer because a secondary index is not available there. How much
slower (if at all) will depend on the amount of data in the table.
To compensate for this problem, avoid the buffer and use the secondary
indexes by adding <TT>bypassing buffer</TT> to the <TT>select</TT>
statement where a secondary index should be used.
</BLOCKQUOTE>
<BLOCKQUOTE>
For example, table <TT>TSTC</TT> contains over 12,000 rows, is
size category 1, is fully buffered, and has a secondary index
on its <TT>pgmna</TT> field. Measurements show that <TT>select
* from tstc <I>bypassing buffer</I>
where pgmna = 'ZTXTEST'</TT> ran 18 times faster on average than
<TT>select * from tstc where pgmna = 'ZTXTEST'</TT>, <I>even though
the table is fully buffered</I>. The first <TT>select</TT> was
resolved in the database using a secondary index on the <TT>pgmna</TT>
field; the second performed a full table scan in the buffer.<BR>
</BLOCKQUOTE>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=600><B>CAUTION</B></TD></TR>
<TR VALIGN=TOP><TD WIDTH=600>
<BLOCKQUOTE>
Be very careful when using <TT>bypassing buffer </TT>on buffered tables that are also updated. If you use it on one <TT>select </TT>statement, you should use it on all <TT>select </TT>statements for that table and all related tables within a single trans-action. If you don't, you will in effect be mixing buffered and unbuffered data. This can cause data inconsistencies in your program and possibly in the database if your program also does updates.
</BLOCKQUOTE>

</TD></TR>
</TABLE>
</CENTER>
<BLOCKQUOTE>
</BLOCKQUOTE>
<H4>Buffering Summarized</H4>

The following are points to remember about buffering tables and
indexing:
<p>
<UL>
<LI>Buffering tables can make your programs run much faster. However,
if carelessly used, buffering can have the opposite effect.
<LI>Buffers sit in RAM on the application server, therefore space
in the buffer is limited. A table that is not accessed often should
not be buffered to conserve buffer space and prevent buffer overflow.
<LI>Tables that are small (size category 0), accessed often, and
rarely updated should be fully buffered.
<LI>Tables that are large (size category &gt; 0) and accessed
often using <TT>select single</TT> should use single-record buffering.
<LI>A table where records from a group are accessed together should
use generic buffering. A partial primary key must identify the
group.
<LI>Tables that are updated often should not be buffered if your
configuration has multiple application servers. Doing so increases
network traffic because the data must be reloaded into the buffers
on the other application servers each time it changes.
<LI>If the table is buffered, use <TT>bypassing buffer</TT> to
obtain the most recent data before allowing it to be updated.
<LI>If possible, use the fields of the primary index in a <TT>where</TT>
clause on buffered tables. If this is not possible, and the table
is large (size category &gt; 0), add <TT>bypassing buffer</TT>
and use fields supported by a secondary index in the database.
</UL>
<H2><A NAME="Summary"><FONT SIZE=5 COLOR=#FF0000>
Summary</FONT></A></H2>
<UL>
<LI>An index is a copy of specific columns of a table sorted in
ascending order.
<LI>Indexes speed up <TT>select</TT> statements. A <TT>select</TT>
should always be supported by an index.
<LI>You can create secondary indexes on a table. Create one when
you cannot use the fields of an existing index in your <TT>where</TT>
clause.
<LI>The fields in a <TT>where</TT> clause should be listed in
your program in the same order as they appear in the index.
<LI>Transaction <TT>ST05</TT> can be used to show which index,
if any, was used by a given <TT>select</TT> statement.
<LI>A table's technical settings can be used to control the data
class, size category, buffering type, and whether logging is enabled.
<LI>The data class determines which tablespace the table will
be created in. The most important data classes are APPL0 (master
data) and APPL1 (transaction data).
<LI>The size category determines the size of the table's initial
and next extents and the maximum number of extents allowed. It
should be chosen so that the initial extent is big enough to hold
the entire table. Secondary extents slow system performance down
and make reorganization necessary.
<LI>Buffering speeds up data access by caching most-often-used
data in RAM on the application server. Buffer space is limited,
so tables should be buffered judiciously.
</UL>
<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1>
<TR VALIGN=TOP><TD WIDTH=288><CENTER><B>DO</B></CENTER></TD><TD WIDTH=288><CENTER><B>DON'T</B></CENTER>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=288>DO place the fields in the where clause in the same order as they appear in the index.
</TD><TD WIDTH=288>DON'T code a select that is unsupported by an index.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=288>DO be generous when choosing a size category.
</TD><TD WIDTH=288>DON'T choose a size category that will cause a table to require a secondary extent.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=288>DO use bypassing buffer when reading a record for update from a buffered table.
</TD><TD WIDTH=288>&nbsp;</TD></TR>
</TABLE>
</CENTER>
<P>
<H2><A NAME="QampA"><FONT SIZE=5 COLOR=#FF0000>
Q&amp;A</FONT></A></H2>

<TABLE>
<TR VALIGN=TOP><TD WIDTH=48><CENTER><B>Q</B></CENTER></TD><TD><B>I can't display some of the screens that you mentioned. I get the error message <TT><B>You are not authorized to use transaction XXXX</B></TT>. How can I see these screens?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=48><CENTER><B>A</B></CENTER></TD><TD>Ask your security administrator for authorization.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=48><CENTER><B>Q</B></CENTER></TD><TD><B>When I display the data buffers using ST02, I see a lot of other buffers there, too. What are they all for?</B>
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=48><CENTER><B>A</B></CENTER></TD><TD>Data buffers are only two of the many buffers kept on an application server. The nametabs (table runtime objects) are all buffered, as well as all programs, menus, and toolbars (a.k.a. CUA or GUI status), screens, and calendars. These bu

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -