Documentation Home
HeatWave User Guide
Related Documentation Download this Manual
PDF (US Ltr) - 3.8Mb
PDF (A4) - 3.8Mb


HeatWave User Guide  /  ...  /  Diagnose Query Offload

5.4.9 Diagnose Query Offload

This topic describes how to debug queries that fail to offload to MySQL HeatWave for execution.

Before You Begin

Setting Secondary Engine Definition

By default, SELECT queries are offloaded to MySQL HeatWave for execution and fall back to the DB System if that is not possible. To force a query to execute on MySQL HeatWave or fail if that is not possible, set the use_secondary_engine variable to FORCED. In this mode, a SELECT statement returns an error if it cannot be offloaded. The use_secondary_engine variable can be set as shown:

Using a SET statement before running queries:

mysql> SET SESSION use_secondary_engine = FORCED;

Using a SET_VAR optimizer hint when issuing a query:

mysql> SELECT /*+ SET_VAR(use_secondary_engine = FORCED) */ ... FROM ...

Enable MySQL Optimizer Trace

If a query fails to offload and you cannot identify the reason, enable tracing and query the INFORMATION_SCHEMA.OPTIMIZER_TRACE table to debug the query.

As of MySQL version 9.0.0, the optimizer trace also includes reasons for not offloading a query due to dynamic offload cost calculation.

  1. To enable MySQL optimizer trace, set the optimizer_trace and optimizer_trace_offset variables as shown:

    mysql> SET SESSION optimizer_trace="enabled=on";
    mysql> SET optimizer_trace_offset=-2;
    Note

    If you encounter the following error:, when executing long queries

    ERROR 3141 (22032): Invalid JSON text in argument 1 to function json_extract: "Missing a name for object member." at position 1038459

    To avoid this error, increase the memory allocated for the optimizer trace, before enabling the trace by executing:

    SET optimizer_trace_max_mem_size = 1024000000;
  2. Issue the problematic query using EXPLAIN. If the query is supported by MySQL HeatWave, the Extra column in the EXPLAIN output shows the following text: Using secondary engine RAPID; otherwise, that text does not appear.

    The following query example uses INTERVAL() function to calculate and display the time interval into which the departure hour falls, based on the specified thresholds (6, 12, 18, 24). by MySQL HeatWave:

    This query is not offloaded to MySQL HeatWave.

    mysql> EXPLAIN SELECT flightno, INTERVAL(HOUR(departure),6,12,18,24) 
    FROM flightschedule\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: flightschedule
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 9828
         filtered: 100
            Extra: NULL
    1 row in set, 1 warning (0.2389 sec)

    Execute the following SELECT statements to detect the error:

    mysql>  SELECT QUERY, TRACE->'$**.Rapid_Offload_Fails' 
    FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE\G
    *************************** 1. row ***************************
    QUERY: EXPLAIN SELECT flightno, INTERVAL(HOUR(departure),6,12,18,24) FROM flightschedule
    TRACE->'$**.Rapid_Offload_Fails': [{"Reason": "HW_ER_1014: The function, [INTERVAL(HOUR(departure),6,12,18,24)], is not supported."}, {"Reason": "HW_ER_1160: Expr, [INTERVAL(HOUR(departure),6,12,18,24)], is not supported."}]
    1 row in set (0.2385 sec)
    mysql> SELECT QUERY, TRACE->'$**.secondary_engine_not_used' 
    FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE\G
    *************************** 1. row ***************************
    QUERY: EXPLAIN SELECT flightno, INTERVAL(HOUR(departure),6,12,18,24) FROM flightschedule
    TRACE->'$**.secondary_engine_not_used': NULL
    1 row in set (0.2385 sec)

    In order to offload this query, replace the INTERVAL() function with multiple IF().

    mysql> EXPLAIN SELECT flightno, IF(HOUR(departure)<6,0,IF(HOUR(departure)<12,1,IF(HOUR(departure)<18,2,3))) FROM flightschedule\G
                *************************** 1. row ***************************
               id: 1
      select_type: NONE
            table: NULL
       partitions: NULL
             type: NULL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: NULL
         filtered: NULL
            Extra: Using secondary engine RAPID. Use EXPLAIN FORMAT=TREE to show the plan.
  3. Query the INFORMATION_SCHEMA.OPTIMIZER_TRACE table for a failure reason. There are two trace markers for queries that fail to offload:

    • Rapid_Offload_Fails

    • secondary_engine_not_used

    To query for the Rapid_Offload_Fails trace marker, issue this query:

    mysql> SELECT QUERY, TRACE->'$**.Rapid_Offload_Fails'
              FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

    To query for the secondary_engine_not_used trace marker, issue this query:

    mysql> SELECT QUERY, TRACE->'$**.secondary_engine_not_used'
              FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
    Note

    If the optimizer trace does not return all of the trace information, increase the optimizer trace buffer size.

  4. If an INFORMATION_SCHEMA.OPTIMIZER_TRACE query trace indicates that a subquery is not yet supported, try unnesting the subquery. For example, the following query contains a subquery and is not offloaded as indicated by the EXPLAIN output, which does not show Using secondary engine.

    mysql> EXPLAIN SELECT COUNT(*) 
              FROM orders o 
              WHERE o_totalprice> (SELECT AVG(o_totalprice) 
              FROM orders 
              WHERE o_custkey=o.o_custkey);
    *************************** 1. row ***************************
               id: 1
      select_type: PRIMARY
            table: o
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 14862970
         filtered: 100.00
            Extra: Using where
    *************************** 2. row ***************************
               id: 2
      select_type: DEPENDENT SUBQUERY
            table: orders
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 14862970
         filtered: 10.00
            Extra: Using where
    2 rows in set, 2 warnings (0.00 sec)

    Re-write as follows to unnest the subquery so that it can be offloaded.

    mysql> EXPLAIN SELECT COUNT(*) 
              FROM orders o, (SELECT o_custkey, AVG(o_totalprice) a_totalprice 
              FROM orders 
              GROUP BY o_custkey)a 
              WHERE o.o_custkey=a.o_custkey AND o.o_totalprice>a.a_totalprice;

The reason reported for a query offload failure depends on the issue or limitation encountered. For common issues, such as unsupported clauses or functions, a specific reason is reported. For undefined issues or unsupported query transformations performed by the optimizer, the following generic reason is reported:

mysql> [{"Reason": "Currently unsupported RAPID query compilation scenario"}]

For a query that does not meet the query cost threshold for MySQL HeatWave, the following reason is reported, and the query is not offloaded:

mysql> [{"Reason": "The estimated query cost does not exceed secondary_engine_cost_threshold."}]

If query does not offload due to Dynamic Offload (newer alternative to cost threshold), the following message is displayed.

mysql> [{message : "HeatWave dynamic threshold rejects query"}]

The query cost threshold prevents queries of little cost from being offloaded to MySQL HeatWave. For information about the query cost threshold, see Section 11.1.1, “MySQL HeatWave Issues”.

To execute such queries using the MySQL HeatWave secondary engine, set the use_secondary_engine system variable to FORCED state using the following syntax options. By default, this variable is set to ON.

mysql> SET SESSION use_secondary_engine = 'FORCED';
Query OK, 0 rows affected (0.3451 sec)

For a query that attempts to access a column defined as NOT SECONDARY, the following reason is reported:

mysql> [{"Reason": "Column risk_assessment is marked as NOT SECONDARY."}]

Columns defined as NOT SECONDARY are excluded when a table is loaded into MySQL HeatWave. See Section 4.2.6.1, “Exclude Table Columns”.

Diagnosing and Resolving Out-of-Memory (OOM) Errors in MySQL Query Execution

If you encounter out-of-memory errors when running queries:

  1. Avoid or rewrite queries that produce a Cartesian product. In the following query, a JOIN predicated is not defined between the supplier and nation tables, which causes the query to select all rows from both tables:

    mysql> SELECT s_nationkey, s_suppkey, l_comment FROM lineitem, supplier, nation
              WHERE s_suppkey = l_suppkey LIMIT 10;
    ERROR 3015 (HY000): Out of memory in storage engine 'Failure detected in RAPID; query 
    execution cannot proceed'.

    To avoid the Cartesian product, add a relevant predicate between the supplier and nation tables to filter out rows:

    mysql> SELECT s_nationkey, s_suppkey, l_comment 
              FROM lineitem, supplier, nation 
              WHERE s_nationkey = n_nationkey AND s_suppkey = l_suppkey LIMIT 10;
  2. Avoid or rewrite queries that produce a Cartesian product introduced by the MySQL optimizer. Due to lack of quality statistics or non-optimal cost decisions, MySQL optimizer may introduce one or more Cartesian products in a query even if a query has predicates defined among all participating tables. For example:

    mysql> SELECT o_orderkey, c_custkey, l_shipdate, s_nationkey, s_suppkey, l_comment
              FROM lineitem, supplier, nation, customer, orders 
              WHERE c_custkey = o_custkey AND o_orderkey = l_orderkey
              AND c_nationkey = s_nationkey AND c_nationkey = n_nationkey AND c_custkey < 3000000
              LIMIT 10;
    ERROR 3015 (HY000): Out of memory in storage engine 'Failure detected in RAPID; 
    query execution cannot proceed'.

    The EXPLAIN plan output shows that there is no common predicate between the first two table entries (NATION and SUPPLIER).

    mysql> EXPLAIN SELECT o_orderkey, c_custkey, l_shipdate, s_nationkey, s_suppkey, l_comment 
              FROM lineitem, supplier, nation, customer, orders
              WHERE c_custkey = o_custkey AND o_orderkey = l_orderkey AND c_nationkey = s_nationkey
              AND c_nationkey = n_nationkey AND c_custkey < 3000000 LIMIT 10;
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: supplier
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 99626
         filtered: 100.00
            Extra: Using secondary engine RAPID
    *************************** 2. row ***************************
               id: 1
      select_type: SIMPLE
            table: nation
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 25
         filtered: 10.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
    *************************** 3. row ***************************
               id: 1
      select_type: SIMPLE
            table: customer
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 1382274
         filtered: 5.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
    *************************** 4. row ***************************
               id: 1
      select_type: SIMPLE
            table: orders
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 14862970
         filtered: 10.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
    *************************** 5. row ***************************
               id: 1
      select_type: SIMPLE
            table: lineitem
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 56834662
         filtered: 10.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID

    To force a join order so that there are predicates associated with each pair of tables, add a STRAIGHT_JOIN hint. For example:

    mysql> EXPLAIN SELECT o_orderkey, c_custkey, l_shipdate, s_nationkey, s_suppkey, l_comment
              FROM SUPPLIER STRAIGHT_JOIN CUSTOMER STRAIGHT_JOIN NATION STRAIGHT_JOIN ORDERS
              STRAIGHT_JOIN LINEITEM WHERE c_custkey = o_custkey and o_orderkey = l_orderkey
              AND c_nationkey = s_nationkey AND c_nationkey = n_nationkey AND c_custkey < 3000000
              LIMIT 10;
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: supplier
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 99626
         filtered: 100.00
            Extra: Using secondary engine RAPID
    *************************** 2. row ***************************
               id: 1
      select_type: SIMPLE
            table: customer
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 1382274
         filtered: 5.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
    *************************** 3. row ***************************
               id: 1
      select_type: SIMPLE
            table: nation
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 25
         filtered: 10.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
    *************************** 4. row ***************************
               id: 1
      select_type: SIMPLE
            table: orders
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 14862970
         filtered: 10.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
    *************************** 5. row ***************************
               id: 1
      select_type: SIMPLE
            table: lineitem
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 56834662
         filtered: 10.00
            Extra: Using where; Using join buffer (hash join); Using secondary engine RAPID
  3. Avoid or rewrite queries that produce a very large result set. This is a common cause of out of memory errors during query processing. Use aggregation functions, a GROUP BY clause, or a LIMIT clause to reduce the result set size.

  4. Avoid or rewrite queries that produce a very large intermediate result set. In certain cases, large result sets can be avoided by adding a STRAIGHT_JOIN hint, which enforces a join order in a decreasing of selectiveness.

  5. Check the size of your data by performing a cluster size estimate. If your data has grown substantially, the MySQL HeatWave Cluster may require additional nodes.

  6. MySQL HeatWave optimizes for network usage by default. Try running the query with the MIN_MEM_CONSUMPTION strategy by setting by setting rapid_execution_strategy to MIN_MEM_CONSUMPTION. The rapid_execution_strategy variable can be set as shown:

    • Using a SET statement before running queries:

      mysql> SET SESSION rapid_execution_strategy = MIN_MEM_CONSUMPTION;
    • Using a SET_VAR optimizer hint when issuing a query:

      mysql> SELECT /*+ SET_VAR(rapid_execution_strategy = MIN_MEM_CONSUMPTION) */ ... FROM ...
    • Unloading tables that are not used. These tables consume memory on MySQL HeatWave nodes unnecessarily. See Section 4.4.2, “Unload Data Manually”.

    • Excluding table columns that are not accessed by your queries. These columns consume memory on MySQL HeatWave nodes unnecessarily. This strategy requires reloading data. See Section 4.2.6.1, “Exclude Table Columns”.

  7. After running queries, consider using MySQL HeatWave Autopilot Advisor for encoding and data placement recommendations. See Section 5.8, “Optimize Workloads for OLAP”.

What's Next

Learn about Auto Scheduling.