There is a misconception that SQL*Net is a protocol or runs on top of the network. These statements are false and, as such, means SQL*Net does not lend itself well to such questions as, Why does SQL*Net run faster on one infrastructure and not another? or Why is SQL*Net faster on the LAN than on the WAN?
While these are valid questions, it must be understood that SQL*Net has two main tasks:
The act of reading and writing to the TCP buffers is an instantaneous process. Therefore delays are normally a result of:
This note describes what can be done from a SQL*Net and an Application perspective. There is very little attempt to inform you how to tune your underlying physical TCP network. That is not the focus of this document.
The most important thing to note here is that most common networking performance issues are not SQL*Net related, but more about how the Application is written, how the network infrastructure is set-up, or how the Oracle database is tuned. This note will touch on some non-Oracle-related issues later.
Tuning SQL*Net revolves around the concept of decreasing the number of packets put on to the network. There are only two things that can be done with SQL*Net to effect network performance and nothing else. These are
Please note that the term nodelay does not mean work faster. Nodelay is a method of disabling Nagle's Algorithm. Refer to the section describing tcp.nodelay for more information.
While SQL*Net can only be tuned in two different ways, there are other factors that can affect performance (These will NOT be covered in detail in this note as they do not pertain to SQL*Net. However, they may be touched on to stress overall importance, for example, Application performance with ARRAYSIZE)
There also should be some basic understandings that some SQL*Net features will naturally cause some degree of performance degradation, such as
An application can be sped up on the network by optimizing the amount of records the application fetches at once. "Sniffing" technology has been used to illustrate how network optimization is done.
In this example SQL*Plus is the application and a SELECT * FROM BIGEMP is issued. The BIGEMP table consists of 4928 rows.In SQL*Plus the amount of records fetched at once is set using ARRAYSIZE.
If the default ARRAYSIZE of 15 in SQL*Plus is used, and the SELECT is issued, the sniffer trace generated shows that 256 packets are sent and received between client and server. This SELECT took 16 seconds.
Now if the ARRAYSIZE in SQLPLUS is set to 49:
and the SELECT is issued, the sniffer trace shows that 154 packets were put on the network, taking 13 seconds.So by changing the ARRAYSIZE, performance has improved by 3 seconds, by reducing the amount of packets on the network by 102.
Below is a simple fun example:
When applying this to TCP, it is important to understand how TCP/IP works. By default the maximum amount of actual 'data', after the headers etc., that can send in a TCP packet is 1460 bytes. In this example, when ARRAYSIZE is set to the default 15, the sniffer shows that the request is for 15 rows at a time and in nearly all cases there is a waste of around 500 bytes of free space in each packet. If these free 500 bytes can be utilized, this TCP packet can be filled and overall fewer packets will be sent and received. In the first case the application asks for 15 rows, so a fetch is sent and it gets one packet of data back with 15 rows in and 500 bytes of empty space, then another fetch is sent and another packet of 15 rows of data with another 500 bytes of free space, etc. When the ARRAYSIZE is set to 49, the application asks for 49 rows and in this case, it fills the first TCP packet fully, and then immediately get another data packet back with the rest of the rows in, and this almost fills the second data packet up.
So an application can tuned by setting a more appropriate ARRAY fetch size thus, it is possible to increase the application's performance. Setting the appropriate ARRAY fetch size is determined by trial and error and using a sniffer (if available). The above example is appropriate for DML and DDL.
In many cases changing the ARRAY fetch size is not an option because many applications are not developed in-house and are provided by a 3rd party vendor. A high percentage of increasing the performance of applications on a network depends on how well it is has been written to perform in conjunction with the protocol that sits underneath it.
From a SQL*Net perspective, the only thing that can be tuned is the SDU size. SDU stands for Session Data Unit. SDU is a buffer at the Network Session (NS) layer from which SQL*Net packets are passed via TDU (Transport Data Unit) at the Network Transport (NT) layer, to the underlying protocol.
By default in version 2.3 (7.3), SDU was set to 4K. However, it changes to 2K in Net*8 and Oracle*Net (8.0 and higher) for dedicated connection. Shared server connections default is 32k.From 11.2 onwards dedicated SDU size increased to 8k, whilst shared server is increased to 65k
Below is a real life example where a customer's application performance was improved by tuning the SDU size.
A company had a large Global Information System written in OCI, where information was initially stored in flat files and then passed via the OCI application into Oracle 8.0.4. The application read the flat file in fixed chunks and then inserted them via Net8 into the database. The data was read from the flat files in 4K blocks but, when passed via OCI over Net8, the amount of data passed over the line equated to 2900 bytes.
With the default SDU size of 2K, each block of data was handled as follows:
If we set SDU to 4K, each block will be handled as follows:
So for each 4K block the OCI application passes to Net8, two TCP packets are sent instead of three by changing the SDU size. Ignoring Acknowledgment packets (ACK's), given that each flat file was 30MB in size, there would be 7680 X 4K blocks of data to send. With SDU at 2K, 23040 packets of data are sent. With SDU set at 4K, 15360 packets are sent, a saving of 7680 data packets.
It could be argued that the same amount of data is being passed over the wire, and it should take the same amount of time given a fixed bandwidth. However each packet has Data Link Control (DLC), TCP, and IP header information which take extra bandwidth. For example 7680 extra packets will use 405K of extra header data. Secondly, each packet will take a finite amount of time to pass through the Network Interface Card (NIC), routers etc, all of which will add time to the overall transaction. Also, if the ACK's in the equation included, packets on the network are lower with SDU set to 4K.
To understand this it is necessary to understand how ACK's work. In the above example, where 2K SDU size was used then there will be three data packets sent. The way TCP works is that if a data packet is sent and if that is the end of transmission, an ACK will be sent back. If some data is sent and it fills two packets, an ACK will be sent on receipt of two consecutive TCP segments. If three data packets are sent and the transmission ends, an ACK will be sent for the first two data packets and an ACK for the third packet. Therefore with an SDU of 2K, there will be three data packets and therefore get two ACK packets per 2900 bytes of data.
With an SDU of 4K there are only two packets per 2900 bytes sent therefore only one ACK is sent. So with an SDU of 2K, 15360 ACK's are sent. And with an SDU of 4K set there will 7680 ACK packets, a saving of 7680 ACK packets.
So as demonstrated by setting SDU appropriately there can be a marked improvement in network and application performance.Again getting the best SDU setting comes down to a bit of maths.
How to set SDU
Example 1. To set SDU size, edit the TNSNAMES.ORA and also the LISTENER.ORA on the desired server, as follows (if either one is not set, the default SDU will be used for SQL*Net communication):
Tnsnames.ora
Listener.ora
For Shared Server connections, formally known as MTS, SDU needs to also be set in the value for Dispatchers. For Example
Example 2
From releases 9.0.1.5, 9.2.0.4 and 10.2.0.1 onwards, the default SDU size can now be changed for connections using SERVICE_NAME. ie Dynamic registeration. Where as example 1, is for SID only, which is static registration
SQLNET.ORA
DEFAULT_SDU_SIZE = 8192
This now means SDU can be set on a per connection basis. Either by adding SDU parameter to local naming configuration file (TNSNAMES.ORA) and the listener configuration file (LISTENER.ORA), or by setting SDU for all Oracle Net connections with the parameter DEFAULT_SDU_SIZE in the SQLNET.ORA file on the client and server. Document 44694.1SQL*Net Packet Sizes (SDU & TDU Parameters)
This is a new parameter for 10g onwards. SEND/RECV_BUF_SIZE alters the underlying TCP's send and receive windows. These windows correspond to the amount of data that can be sent before a TCP acknowledgment is received. Some network delays can be attributed to the time spent waiting on these ACKs. The time spent waiting on TCP acknowledgments is seen mostly in WAN environments. Little time is spent waiting on ACKs in LAN environments.
For more information, please refer to Note 260984.1
This is all that can be done from an Application or SQL*Net perspective. However if this is done right but performance is still an issue, then there are other things which are degrading performance on the WAN.
Set in the PROTOCOL.ORA file for Oracle8i and in the SQLNET.ORA file for Oracle9i and up.
NOTE: tcp.nodelay is not a performance feature. It alters the way packets are delivered on the network thereby possibly effecting performance. It is recommended NOT to alter this parameter unless it is known what the outcome will be.
Under certain conditions for some applications using TCP/IP, Oracle Net packets may not get flushed immediately to the network. Most often, this behavior occurs when large amounts of data are streamed. The implementation of TCP/IP itself is the reason for the lack of flushing, causing unacceptable delays. To remedy this problem, specify no delays in the buffer flushing process. This is not a SQL*Net feature but rather the ability to set the persistent buffering flag at the TCP layer.
"tcp.nodelay" activates/deactivates Nagle's Algorithm. More information on Nagle's Algorithm can be found in RFC 896.
As mentioned towards top of this note, as well as tuning the application, the majority of performance issues over the network comes down to the components of the network itself. If performance issues are experienced, please check the following (greater detail would come from the System or network Administrator)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/13750068/viewspace-1390804/ ,如需转载,请注明出处,否则将追究法律责任。