Optimizing SQL Anywhere PerformanceOver a WAN
Introduction
This document discusses tuning performance for an SQL Anywherenetwork server that is running over a WAN. TCP/IP is theprotocol of choice for WAN implementations and is the main focus of thisdocument. Note that network performance tuning is an iterative process ofdetermining what works best with a particular application and network.
The recommended steps for optimizing the performance of your application are:
- Measure the performance of the network you plan to run your application on.
- Based on the network performance, tune your application to reduce requestsand/or to reduce the amount of data transferred.
- Based on the network performance, tune SQL Anywhere’s serveroptions and connection parameters to maximize performance.
- Consider the implications of your tuning on LANs or same-machine operation.
In many cases, tuning an application can have a more significant performanceimpact than tuning SQL Anywhere.
Measuring network performance
Latency and throughput can be used together to describe the performance of anetwork. Latency refers to the time delay between when one machine sends apacket of data and the second machine receives the data (for example, if thesecond machine receives the data 10 ms later than the first machine sent it, thelatency is 10 ms). Throughput refers to the amount of data that can be transferredin a given time (for example, if a one machine sends 1000 KB of data, and it takes5 seconds for all of it to be received by the second machine, the throughput is200 KB/s). On a LAN, latency is typically less than 1 ms, and throughput istypically 10 MB/s or more. On a WAN, the latency is typically significantly higher(perhaps 1 ms to 500 ms), and the throughput is typically lower(perhaps 6 KB/s to 2 MB/s).
You can measure network latency between two machines by the round trip timereported by the system’s ping utility. The round trip time is the latency to transferdata from one machine to a second machine plus the latency to transfer data fromthe second machine back to the first machine. You can measure networkthroughput by copying a file of a known size of at least 200 KB from one machineto a second machine and timing the copy. This copy could be performed as aregular file copy, using FTP, or by downloading a file using an Internet browser.
Another way to get an estimate of both latency and throughput between two machines is to run a SQL Anywhere network server on one machine (ensure the database server is not already heavily loaded) and run the following on the second machine:
dbping -d -c <connection string to network server> -st 10
Note that for high throughput networks, the throughput values reported by dbping may be lower than the actual throughput of the network.
To get reasonable SQL Anywhere performance on a network that hashigh latency, but reasonable throughput, the number of requests made by theclient must be minimized. If a network has reasonable latency, but low throughput,the amount of data transferred between the client and server must be minimized.
Tuning your application to improve WAN performance
Changing your application to implement the following suggestions generallyreduces both the number of requests and the amount of data transferred. Thesesuggestions can also help improve application performance in any environment(standalone, LAN, and WAN).
- Move logic that requires many SQL statements from the application to one ormore stored procedures or functions.
- If the same basic SQL statement is used more than once, consider preparingthe statement once and executing it multiple times with different parameters.
- Ensure your application is not executing queries or SQL statements more oftenthan necessary. If a particular query is executed more than once, considerchanging the application to cache the results the first time the query isexecuted, and then use the cached values instead of re-executing the query.
- Combine queries that get one property, function, or variable value into onemultiple-column query. Suppose you want to execute the following queries:SELECT current user, SELECT @@servername, and SELECT connection_property('BytesSent'). Instead of executing three queries,use a single query:
SELECT current user, @@servername, connection_property( 'BytesSent' )
- Avoid doing joins in the application with multiple queries if it is possible to dothe join in the server. If an application executes a query, and then executes asecond query using the result from the first query, you may essentially bejoining multiple queries together in your application. If it is possible to do thejoin using one query instead of many, this can significantly improveperformance. As a simple example, if your application executed the querySELECT T.x FROM T WHERE <conditions on T> ORDER BY <order>, andthen for each value of T.x, did SELECT R.y FROM R WHERE R.z = <value of T.x>, then this can be combined into the single query SELECT T.x, R.y FROM T, R WHERE <conditions on T> AND R.z = T.x ORDER BY <order>.
- Avoid setting options after initializing a connection, avoid DDL (Data Definition Language), and avoid dropping connection variables. These can cause client statement caching to not be able to reuse a cached statement. These can also cause cached plans to not be able to be reused. Using DDL in a production system can result in a number of potential performance issues including overall slow performance during the DDL operation, and side effects such as procedures needing to be reloaded into the server's memory.
- Avoid many short running connections when a single long running connection could be used instead. In cases where this is not possible (such as from a web server), consider using connection pooling. SQL Anywhere has built-in connection pooling that can be configured to improve performance depending on the application (for the SQL Anywhere .NET Data Provider use the POOLING connection parameter, and for other client APIs use the ConnectionPool connection parameter).
- When working with third-party development tools (for example, PowerBuilder,Visual Basic, or Delphi), check whether there are any application-specificsettings you can make to increase your performance. For example, inPowerBuilder, changing the BLOCK connection property sometimes improvesapplication performance over a WAN.
Reducing the number of requests
The following suggestions may reduce the number of requests, which isparticularly beneficial if your network has high latency. These suggestions mayalso improve performance on other networks.
- Use bound columns to fetch data instead of using get data. This reduces thenumber of requests, especially when fetching the first row from a cursor.
- Combine SQL statements into a batch (a sequence of SQL statementsseparated by semicolons that are all executed as if they were one statement)where possible.
- Disable autocommit and commit explicitly only when necessary to eliminateextra commit requests (a commit or rollback should be performed in mostcases before waiting on user input to avoid excessive blocking).
- Use wide fetches (also referred to as increasing the row set size) and wideinserts (also referred to as using arrays of parameter values). These fetch orinsert multiple rows in one request, instead of using one request per row.Prefetch also fetches more than one row per request.
Reducing the amount of data transferred on the network
The following suggestions generally reduce the amount of data transferred, whichis particularly beneficial if your network has low throughput. These suggestionsare unlikely to decrease performance on other networks.
- Consider using stored procedures for large database queries. This eliminatesthe need to send a large statement to the server across the network byallowing you to send a small CALL statement to execute the query.
- If you know that you will only be fetching the first row (or first few rows) of aquery, add a FIRST or TOP n clause to the query. If you want to skip the firstfew rows in a query, use the START AT clause. These clauses prevent rowsthat you won't use from being transferred, particularly if prefetch is enabled.Adding these clauses can also help the query optimizer know how to executethe query more efficiently.
Tuning SQL Anywhere toimprove WAN performance
The following suggestion can tune SQL Anywhere so your applicationruns better on a WAN, independent of your network’s latency and throughput.
- Consider increasing the liveness timeout if your connections are droppedbecause of liveness. Increasing this value does not improve performance, butyou should increase this value if your connection keeps timing out due toliveness. The option can be set at the client (using the LivenessTimeoutconnection parameter) or the server (-tl). Using the LivenessTimeoutconnection parameter, you could change the liveness timeout only for WANconnections.
In most cases the following suggestions reduce the number of requests, which isparticularly beneficial if your network has high latency:
- Consider changing the prefetch behavior. When your application fetches a row,SQL Anywhere may prefetch additional rows depending on thecursor type and other factors. Prefetch can reduce requests and significantlyimprove performance, particularly on high latency networks when a largenumber of rows are fetched from a cursor. Note that absolute fetches, relativenegative or relative 0 fetches, rollbacks, and certain get data operations cancause prefetch rows to be discarded and re-fetched, which decreases performance. Prefetch is best used on forward-only, read-only cursors, whenmore than just the first row is fetched. If your application fetches many rowsfrom each cursor and only uses fetch next operations, using the PrefetchRowsand PrefetchBuffer connection parameters may improve performance, although the default values are usually sufficient.Prefetching many rows when the application only fetches part of the result setcould potentially decrease performance. Additionally, an ODBC and JDBC applications can benefit from the PrefetchOnOpen connection parameter ifmany cursor opens are done. Avoid the use of value sensitive cursor types (including ODBC DYNAMIC and KEYSET and ESQL SENSTIVE and SCROLL types) unless they are absolutely necessary for correctness since these cursors cannot prefetch.
- Consider using the LazyClose connection parameter, particularly when manycursors are opened and closed. This eliminates an extra request when closinga cursor.
The following suggestions may be beneficial if your network has low throughput:
- Consider using communication compression (the server’s -pc option or theclient’s Compression connection parameter). Using communicationcompression reduces the amount of data transferred, and the number ofpackets transferred, but it does not reduce the number of requests.Communication compression can be particularly beneficial on large fetches,multi-row fetches, or BLOB operations. Note that communication compressionuses more CPU and memory on both the client and the server. As a result, itcan cause poorer performance in some cases, and in most cases decreasesperformance on a LAN. By using the client’s Compression connectionparameter, you can enable communication compression for WAN connectionsonly.
- Consider using the ReceiveBufferSize and SendBufferSize TCP/IP protocoloptions on both the client and the server. These options pre-allocate memoryin the protocol stack for sending and receiving TCP/IP packets. Preallocation ofmemory inside the protocol stack can increase client/server performance fornetwork-intensive applications. The default value is machine dependent, andvalues in the range of approximately 65 536 to 262 144 bytes are reasonablefor experimentation.
- If your application only uses the first row from a cursor, disabling prefetch usingthe DisableMultiRowFetch connection parameter can improve performance.Instead of using DisableMultiRowFetch, you may get better performance bychanging the application to use the FIRST clause on queries where you onlyfetch the first row as suggested in the application tuning section above. UsingDisableMultiRowFetch can cause poorer performance in many cases, includingon faster networks.
Here are some suggested settings you can use to start tuning. Start with thesesettings and adjust them in your test environment to see how they affectperformance. Try adding and removing the server options and connectionparameters mentioned above and see how they affect performance. It is not anexact science and requires some trial and error to get the best performance in your particular network environment with your particular application.
For information about potential LAN performance implications, see"Performance implications for LANs and same-machine operation" below.
Database server command-line options
dbsrv16 -x TCPIP(SendBufferSize=100000;ReceiveBufferSize=100000)-n server_name ...
Client connection parameters
Note that PrefetchOnOpen is for ODBC and OLE DB only. If you do not see any improvement from the SendBufferSize and ReceiveBufferSize, it is recommended that instead of the CommLinks=TCPIP(…) in the example below, you use HOST=w.x.y.z:port for simplicity. A host name or IPv6 address can be used instead of w.x.y.z, and :port is not necessary if the server is using port 2638 (the default).
"ServerName=server_name; Compression=Yes; CommLinks=TCPIP(Host=w.x.y.z:port; DoBroadcast=NONE; SendBufferSize=100000; ReceiveBufferSize=100000); PrefetchOnOpen=Yes; LazyClose=Yes; ..."
Note
The options listed here are communication oriented. There are other optionsto consider that can make the server more efficient in all environments (forexample, cache size and database page size). Refer to your SQL Anywhere documentation for more information.
Performance implications for LANs andsame-machine operation
If your application is also going to be running in a LAN environment, don't forget totest your SQL Anywhere communication options there as well, asthere may be a need to adjust these options for that environment.
All of the application tuning suggestions mentioned in this document typicallyimprove or at least maintain performance in LAN and same-machineconfigurations.
The following SQL Anywhere WAN tuning suggestions may causepoorer performance on a LAN or for same-machine operation. They should onlybe enabled for WAN clients, or after LAN testing has verified they also increaseperformance on the LAN:
- Changing the liveness timeout can cause severed connections to goundetected for long periods of time.
- Enabling communication compression often results in slower performance onLANs where the increased memory and CPU usage outweigh potentialthroughput gains.
- Changing the prefetch settings (PrefetchRows, PrefetchBuffer andDisableMultiRowPrefetch). All prefetch settings have the potential to increaseor decrease performance depending on the application and environment.