Informix

Informix

Connect with Db2, Informix, Netezza, open source, and other data experts to gain value from your data, share insights, and solve problems.

 View Only
  • 1.  Query using temp table is much faster then join/subquery

    Posted 23 days ago

    I have problem with query (duration 40s), when I use temp table is much faster (<2s). 
    Can I do anything to improve query? Using temporary tables is cumbersome.

    Here is sqexplain, first for regular query, second with temp table:


    QUERY: (OPTIMIZATION TIMESTAMP: 05-30-2025 09:38:28)
    ------
    select
    et_filename,
    REPLACE(transfer.err_text, 'Export:','') Dateiname,
    transfer.status Prio,
    transfer.l_timestamp Export,
    sftp.l_timestamp SCPExport
    FROM et_transfer
    LEFT JOIN gwy_test01 transfer ON  transfer.prog = 'TransferFromHop' AND transfer.status > 0 and DATE(transfer.l_timestamp) >= TODAY
    AND transfer.err_text like 'Export %' AND LOWER(REPLACE(transfer.err_text, 'Export: ','')) LIKE  LOWER(et_filename || '_' || to_char(sysdate, '%Y%m%d')  || '%' )
    LEFT JOIN gwy_test01 sftp ON  transfer.err_text = sftp.err_text
     and sftp.prog = 'SFTPTransfer' AND sftp.status > 1 AND DATE(sftp.l_timestamp) = TODAY
    WHERE et_check_hour <= (CURRENT::DATETIME HOUR TO HOUR)::char(2)::INTEGER
    AND
    (
    transfer.l_timestamp IS NULL
    OR
    (
    transfer.l_timestamp < CURRENT  - 15 UNITS MINUTE
    AND sftp.l_timestamp IS NULL
    )
    )

    Estimated Cost: 2014028
    Estimated # of Rows Returned: 1632265216

              1) gwy.et_transfer: SEQUENTIAL SCAN

                    Filters: gwy.et_transfer.et_check_hour <= CURRENT year to fraction(3)::datetime hour to hour::char(2)::integer

              2) gwy.transfer: INDEX PATH

                (1) Index Name: gwy.gwy_6_idx1
                    Index Keys: prog status l_timestamp err_text   (Key-First)  (Serial, fragments: ALL)
                    Lower Index Filter: (gwy.transfer.prog = 'TransferFromHop' AND gwy.transfer.status > 0 )
                    Index Key Filters:  (gwy.transfer.err_text LIKE 'Export %' )

            ON-Filters:((((gwy.transfer.prog = 'TransferFromHop' AND gwy.transfer.status > 0 ) AND DATE (gwy.transfer.l_timestamp ) >= TODAY ) AND gwy.transfer.err_text LIKE 'Export %' ) AND LOWER(REPLACE (gwy.transfer.err_text , 'Export: ' , '' ) ) LIKE LOWER((((gwy.et_transfer.et_filename || '_' )|| TO_CHAR (SYSDATE year to fraction(5), '%Y%m%d' ) )|| '%' )) )
            NESTED LOOP JOIN(LEFT OUTER JOIN)

          3) gwy.sftp: INDEX PATH

            (1) Index Name: gwy.gwy_5_idx1
                Index Keys: prog status l_timestamp   (Serial, fragments: ALL)
                Lower Index Filter: (gwy.sftp.prog = 'SFTPTransfer' AND gwy.sftp.status > 1 )

        ON-Filters:(((gwy.transfer.err_text = gwy.sftp.err_text AND gwy.sftp.prog = 'SFTPTransfer' ) AND gwy.sftp.status > 1 ) AND DATE (gwy.sftp.l_timestamp ) = TODAY )
        DYNAMIC HASH JOIN (LEFT OUTER JOIN)
            Dynamic Hash Filters: gwy.transfer.err_text = gwy.sftp.err_text

    PostJoin-Filters:(gwy.transfer.l_timestamp IS NULL OR (gwy.sftp.l_timestamp IS NULL AND gwy.transfer.l_timestamp < CURRENT year to fraction(3)- interval(        15) minute(9) to minute ) )


    Query statistics:
    -----------------

      Table map :
      ----------------------------
      Internal name     Table name
      ----------------------------
      t1                et_transfer
      t2                transfer
      t3                sftp

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t1     171        171       171        00:00.00   9

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t2     0          21327     17683965   00:31.01   11425

      type     rows_prod  est_rows  time       est_cost
      -------------------------------------------------
      nljoin   171        145894    00:36.35   1957177

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t3     129359     22376     129359     00:00.35   13572

      type     rows_prod  est_rows  rows_bld  rows_prb  novrflo  time       est_cost
      ------------------------------------------------------------------------------
      hjoin    171        1632265216  129359    171       11       00:37.73   2014028


    QUERY: (OPTIMIZATION TIMESTAMP: 05-30-2025 09:40:33)
    ------
    select *
    from gwy_test01 transfer
    where
     transfer.prog = 'TransferFromHop' AND transfer.status > 0 and DATE(transfer.l_timestamp) >= TODAY and transfer.err_text like 'Export %'
    into temp gwytmp with no log

    Estimated Cost: 4
    Estimated # of Rows Returned: 1

      1) gwy.transfer: INDEX PATH

            Filters: (((DATE (gwy.transfer.l_timestamp ) >= TODAY AND gwy.transfer.prog = 'TransferFromHop' ) AND gwy.transfer.err_text LIKE 'Export %' ) AND gwy.transfer.status > 0 )

        (1) Index Name: gwy.gwy_3_idx3
            Index Keys: l_timestamp (desc)   (Serial, fragments: ALL)
            (fragments might be eliminated at runtime because filter contains
    runtime constants)
            Upper Index Filter: gwy.transfer.l_timestamp >= EXTEND (TODAY ,year to second)


    Query statistics:
    -----------------

      Table map :
      ----------------------------
      Internal name     Table name
      ----------------------------
      t1                transfer
      t2                gwytmp

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t1     0          1         1          00:00.00   4

      type     table  rows_ins   time
      -----------------------------------
      insert   t2     0          00:00.00


    QUERY: (OPTIMIZATION TIMESTAMP: 05-30-2025 09:40:33)
    ------
    select
    et_filename,
    REPLACE(transfer.err_text, 'Export:','') Dateiname,
    transfer.status Prio,
    transfer.l_timestamp Export,
    sftp.l_timestamp SCPExport
    FROM et_transfer
    LEFT JOIN gwytmp transfer ON LOWER(REPLACE(transfer.err_text, 'Export: ','')) LIKE  LOWER(et_filename || '_' || to_char(sysdate, '%Y%m%d')  || '%' )
    LEFT JOIN gwy_test01 sftp ON  transfer.err_text = sftp.err_text
     and sftp.prog = 'SFTPTransfer' AND sftp.status > 1 AND DATE(sftp.l_timestamp) = TODAY
    WHERE et_check_hour <= (CURRENT::DATETIME HOUR TO HOUR)::char(2)::INTEGER
    AND
    (
    transfer.l_timestamp IS NULL
    OR
    (
    transfer.l_timestamp < CURRENT  - 15 UNITS MINUTE
    AND sftp.l_timestamp IS NULL
    )
    )

    Estimated Cost: 19202
    Estimated # of Rows Returned: 1913148

              1) gwy.et_transfer: SEQUENTIAL SCAN

                    Filters: gwy.et_transfer.et_check_hour <= CURRENT year to fraction(3)::datetime hour to hour::char(2)::integer

              2) gwy.transfer: SEQUENTIAL SCAN  (Serial, fragments: ALL)

            ON-Filters:LOWER(REPLACE (gwy.transfer.err_text , 'Export: ' , '' ) ) LIKE LOWER((((gwy.et_transfer.et_filename || '_' )|| TO_CHAR (SYSDATE year to fraction(5), '%Y%m%d' ) )|| '%' ))
            NESTED LOOP JOIN(LEFT OUTER JOIN)

          3) gwy.sftp: INDEX PATH

            (1) Index Name: gwy.gwy_5_idx1
                Index Keys: prog status l_timestamp   (Serial, fragments: ALL)
                Lower Index Filter: (gwy.sftp.prog = 'SFTPTransfer' AND gwy.sftp.status > 1 )

        ON-Filters:(((gwy.transfer.err_text = gwy.sftp.err_text AND gwy.sftp.prog = 'SFTPTransfer' ) AND gwy.sftp.status > 1 ) AND DATE (gwy.sftp.l_timestamp ) = TODAY )
        DYNAMIC HASH JOIN (LEFT OUTER JOIN)
            Dynamic Hash Filters: gwy.transfer.err_text = gwy.sftp.err_text

    PostJoin-Filters:(gwy.transfer.l_timestamp IS NULL OR (gwy.sftp.l_timestamp IS NULL AND gwy.transfer.l_timestamp < CURRENT year to fraction(3)- interval(        15) minute(9) to minute ) )


    Query statistics:
    -----------------

      Table map :
      ----------------------------
      Internal name     Table name
      ----------------------------
      t1                et_transfer
      t2                transfer
      t3                sftp

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t1     171        171       171        00:00.00   9

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t2     0          1         0          00:00.00   2

      type     rows_prod  est_rows  time       est_cost
      -------------------------------------------------
      nljoin   171        171       00:00.00   356

      type     table  rows_prod  est_rows  rows_scan  time       est_cost
      -------------------------------------------------------------------
      scan     t3     129359     22376     129359     00:00.34   13572

      type     rows_prod  est_rows  rows_bld  rows_prb  novrflo  time       est_cost
      ------------------------------------------------------------------------------
      hjoin    171        1913148   129359    171       11       00:01.37   19202



    ------------------------------
    G W
    ------------------------------


  • 2.  RE: Query using temp table is much faster then join/subquery

    Posted 23 days ago

    GW:

    First step: Change OPTCOMPIND in your ONCONFIG file from 2 to 0:

    onmode -wf OPTCOMPIND=0

    Then try running the original query again. That query is taking 40sec and over 37 of those seconds are being consumed to build and query a hash table for a hash join. Changing the OPTCOMPIND will force the optimizer to avoid using hash joins which should make a significant difference.

    Next, I notice that some of the estimated rows for various steps in the sqlexplain output are vastly different from the actual rows produced by that step. That likely means that your data distributions are either out-of-date or insufficiently detailed for the optimizer to make good decisions. I STRONGLY suggest that you run my dostats utility on at least those tables involved in the query and try to run it again. I suspect that that will be the final nail in this problem.

    If you do not have my dostats utility go to my web site (My Utilities

    ASK Database Management remove preview
    My Utilities
    Utils2_ak is my primary package of utilities. This is the May 18, 2025 release. Included: dbping.ec - Tests connections and reports connection time as well as the actual host and...
    View this on ASK Database Management >

    ) and download my utils2_ak package (free & open source), build it (on Linux just unzip the archive and type "make" - for other platforms there are comments in the Makefile and in the myschema.mk.norcs file in the myschema.d subdirectory and notes in the Building text file).

    Art



    ------------------------------
    Art S. Kagel, President and Principal Consultant
    ASK Database Management Corp.
    www.askdbmgt.com
    ------------------------------



  • 3.  RE: Query using temp table is much faster then join/subquery

    Posted 19 days ago

    Thanks for suggestion.
    I tried various settings , in sql:

    SET ENVIRONMENT OPTCOMPIND '0/1/2';
    SET OPTIMIZATION HIGH/LOW;

    (total 7)

    I tried with :
    onmode -wf OPTCOMPIND=0

    I run with different settings for "update statistics high/medium/low "

    I always get same time (50s+-3s)

    Execution plans always was similar.




    ------------------------------
    G W
    ------------------------------