Wednesday, November 25, 2015

NSSQL - Control-statements

Control-statements are compiler-directives. Their impact is only at compile time. The resulting compiled queries are stored in the Query Execution Plan (QEP). At runtime this static QEP is used to access the database.

The scope of a control-statement extends can be ended by an other control-statement. All SQL-statements in the scope of a control-statement are influenced by this control-statement.
Control-statements that are of importance for a certain have to be coded bfore that query.
General control-statements (e.g. control-statements tha are used to influence table locks) are usually coded in the first part of a program.


In some cases a control-statement is needed to influence only one query. For instance to control the access-path of that query or to influence the block-buffering. It is good practive to code such a control-statement right in front of the query that has to be influenced and to code another neutralizing control-statement right after that query in order not to affect the following queries.

Example:
 *----------------------------------------------------------------------
  S080-COUNT-REK-MULTI-OVK SECTION.
 *----------------------------------------------------------------------
       EXEC SQL
        CONTROL QUERY INTERACTIVE ACCESS ON
       END-EXEC

       EXEC SQL
        SELECT COUNT (DISTINCT MULTI_OVK_NR)
          INTO :WS-COUNT-MULTI-OVK
          FROM =OVK-EXTRACT-VIN
         WHERE VIN_PRODUKT_NR    = :VIN-PRODUKT-NR    OF WS-OVK-EXTRACT-VIN
           AND REK_NR            = :REK-NR            OF WS-OVK-EXTRACT-VIN
           AND INTERN_REK_VOLGNR = :INTERN-REK-VOLGNR OF WS-OVK-EXTRACT-VIN
           AND MULTI_OVK_NR      > 0
         STABLE ACCESS
       END-EXEC

       EXEC SQL
        CONTROL QUERY INTERACTIVE ACCESS OFF
       END-EXEC

 *----------------------------------------------------------------------
  S090-COUNT-REK-BBO SECTION.
 *----------------------------------------------------------------------
       EXEC SQL
        SELECT COUNT(*)
          INTO :WS-COUNT-BBO
          FROM =OVK-EXTRACT-VIN
         WHERE VIN_PRODUKT_NR    = :VIN-PRODUKT-NR    OF WS-OVK-EXTRACT-VIN
           AND REK_NR            = :REK-NR            OF WS-OVK-EXTRACT-VIN
           AND INTERN_REK_VOLGNR = :INTERN-REK-VOLGNR OF WS-OVK-EXTRACT-VIN
           AND MULTI_OVK_NR      = 0
         STABLE ACCESS
       END-EXEC

BEWARE

Never use CONTROL TABLE <tablename> without any options. This results in returning all control options for that table to the default values. Are you sure you want to do that?

Correlation names

The CONTROL TABLE control-statement can be used with a correlation name. The control-statement only affects queries where that correlation name is used.

Example (OEV is the correlation name):
       EXEC SQL
        CONTROL TABLE =OVK-EXTRACT-VIN AS OEV
                ACCESS PATH INDEX =OVK-EXTRACT-VIN-I2
       END-EXEC.

       EXEC SQL
        DECLARE A_CURSOR CURSOR FOR
        SELECT …
         FROM =OVK-EXTRACT-VIN OEV
         WHERE …
         REPEATABLE ACCESS IN EXCLUSIVE MODE
         FOR UPDATE OF …
       END-EXEC.

Extract from explain:
Operation 1.0  : Scan
    Table             : \ZT1.$DATA.OK13WDB.OVKVIN
                        with correlation name OEV
    Access type       : Record locks, repeatable access
    Lock mode         : Chosen by the system
    Column processing : Requires retrieval of 8 out of 71 columns

      Access path 1     : Alternate \ZT1.$DATA.OK13WDB.OVKVINI2, path forced
      SBB for reads     : Virtual
      Begin key pred.   : REK_NR = :REK-NR         OF WS-OVK-EXTRACT-VIN
      End key pred.     : REK_NR = :REK-NR         OF WS-OVK-EXTRACT-VIN

NSSQL Tips #4

The following statements are forbidden because they result in poor maintainability.

·         SELECT * FROM <table>
Using SELECT * also may result in a less efficient access-padh. Using VSBB or Index-Only access may not be chosen.

Specify all needed columns:
SELECT (col1, col2)

·         INSERT INTO <table> VALUES (valcol1, valcol2)

Specify all columns. (Columns with default-values may be left out).

INSERT INTO <table> (col1, col2) VALUES (valcol1, valcol2)

The following statement is forbidden because it often gives unexpected results.

·         CONTROL TABLE <tabel>
Rather use a control-statement with the needed option and the correct (default) value.

Tuesday, November 24, 2015

Increasing the TMF Lock Limit

Few options for Increasing the TMF Lock limit


Option 1
Put the alternate key files on other volumes. Since the locks are counted by volume and not by file this may solve the issue.

Option 2
Increase the maximum lock limit by use of SCF application.
You can control the number of locks that a transaction can hold on a specific volume and lock escalation by using SCF to change MaxLocksPerTCB to a maximum of 100,000. Use this command:
More information can be found in the attached manual.

SCF ALTER $volume, MAXLOCKSPERTCB n

2-> info $data4,detail
STORAGE - Detailed Info Magnetic DISK \ETDEV1.$DATA4
Common Disk Configuration Information:
*BackupCpu............................. 1
*HighPin............................... ON
*PrimaryCpu............................ 0
*Program............................... $SYSTEM.SYSTEM.TSYSDP2
*StartState............................ STARTED

Disk Type Specific Information:
*AuditTrailBuffer/SQLMXBuffer (MB)..... 0
*AutoRevive............................ OFF
*AutoSelect............................ n/a
*AutoStart............................. ON
*CapacityMismatch...................... OFF
*CBPoolLen............................. 1000
*FastBulkWrite......................... OFF
*FSTCaching............................ OFF
*FullCheckpoints....................... ENABLED
*HaltOnError........................... 1
*LKIDLongPoolLen....................... 8
*LKTableSpaceLen....................... 15
*MaxLocksPerOCB........................ 5000 (This is it!!!)
*MaxLocksPerTCB........................ 5000 (This is it!!!)
*NonAuditedInsert...................... OFF
*NumDiskProcesses...................... 4
*OSSCaching............................ ON
*PhysvolSelect......................... n/a

*Pool.................................. None

Wednesday, November 18, 2015

Industry Standard Definitions - On Availablity

High Availability (HA)– 
     The attribute of a system to provide service during defined periods, at acceptable or agreed upon levels and masks UNPLANNED OUTAGES from end-users. It employs Fault Tolerance; Automated Failure Detection, Recovery, Bypass Reconfiguration, Testing, Problem and Change Management

Continuous Operations (CO)
     Attribute of a system to continuously operate and mask PLANNED OUTAGES from end-users.  It employs Non-disruptive hardware and software changes, non-disruptive configuration, software coexistence .


Continuous Availability (CA)
     Attribute of a system to deliver non disruptive service to the end user 7 days a week, 24 HOURS A DAY (there are no planned or unplanned outages). It includes the ability to recover from a site disaster by switching computing to a second site.

Wednesday, November 11, 2015

NSSQL TIPS #3

Avoid sorting

Avoid sorting of large amounts of data. It takes time and has a negative influence on performance.
Sorting may be used in the following cases:
-       ORDER BY
-       GROUP BY
-       DISTINCT
-       UNION (not with UNION ALL)
-       MERGE JOIN


Avoid re-opening a cursor with a large sort in its access-path. If such a cursor is closed, e.g. due to a COMMIT, then reopening the cursor to continue processing will result in repeating of the sort. This is killing for performance. If possible open the cursor with BROWSE ACCESS outside a TMF transaction.

NSSQL TIPS #2

Functions in search-conditions

Do not use functions on table-columns in a search-condition. This may result in a scan because the optimizer will not consider any available index on this column.
Rather use a function on the host-variable.

Example:
WHERE JULIANSTIMESTAMP(datum_kolom) = :hostvariabele
Results in a full table scan

Alternative:

WHERE datum_kolom = converttimestamp(:hostvariabele)

Wednesday, November 04, 2015

CODECOVERAGE

•Measure quality of testing;

•What lines of code has been hit during testing

•Specify CODECOV option at compile time

•Specify -l pgo DLL at link time

•Perform GAT/PAT testing (measure)

•Run HTML reporter on PC




Tuesday, November 03, 2015

NQSQL TIPS


Select unknown values only




For performance reasons it is better to select as few columns as possible. The optimizer may choose techniques like Index-only access. Besides it makes the query easier to read and maintain.
In the following query selects five columns of table FOTB100. The first two columns are also used in the where-clause with “=”-predicates. So the values of these columns are no surprise and therefore it is not necessary to select these columns. So leave them out of the column-list.
 SELECT
        REK_NR
      , PE_TX_REF
      , ST_TS
      , ST
      , PRI
 INTO
       :REK-NR          OF FINTXSTH
     , :PE-TX-REF     OF FINTXSTH
     , :ST-TS              OF FINTXSTH
     , :ST                   OF FINTXSTH
     , :PRI                  OF FINTXSTH
FROM  FOTB100
 WHERE  REK_NR     = :REK-NR    OF FINTXST
   AND  PE_TX_REF  = :PE-TX-REF OF FINTXST



Monday, November 02, 2015

Unicode - UTF 8, 16 and 32 Details

  • UTF8 is variable 1 to 4 bytes.
  • UTF16 is variable 2 or 4 bytes.
  • UTF32 is fixed 4 bytes.
In brief, UTF32 uses 32-bit values for each character. That allows them to use a fixed-width code for every character.
UTF16 uses 16-bit by default, but that only gives you 65k possible characters, which is nowhere near enough for the full Unicode set. So some characters use pairs of 16-bit values.
And UTF8 uses 8-bit values by default, which means that the 127 first values are fixed-width single-byte characters. (the most significant bit is used to signify that this is the start of a multi-byte sequence, leaving 7 bits for the actual character value) All other characters are encoded as sequences of up to 4 bytes (if memory serves).
Unicode is a standard and about UTF-x you can think as a technical implementation for some practical purposes:
  • UTF-8 - "size optimized": best suited for Latin character based data (or ASCII), it takes only 1 byte per character but the size grows accordingly symbol variety (and in worst case could grow up to 6 bytes per character)
  • UTF-16 - "balance": it takes minimum 2 bytes per character which is enough for existing set of the mainstream languages with having fixed size on it to ease character handling (but size is still variable and can grow up to 4 bytes per character)
  • UTF-32 - "performance": allows using of simple algorithms as result of fixed size characters (4 bytes) but with memory disadvantage