From fc0c157aaa0b1603a321890c6c43b4b6b5e3b2e3 Mon Sep 17 00:00:00 2001
From: Monty <monty@mariadb.org>
Date: Fri, 5 Nov 2021 13:06:14 +0200
Subject: [PATCH] Simple optimization to speed up some handler functions when
 checking killed

- Avoid checking for has_transactions if killed flag is not checked
- Simplify code (Have checked with gcc -O3 that there is improvements)
- Added handler::fast_increment_statstics() to be used when a handler
  functions wants to increase two statistics for one row access.
- Made check_limit_rows_examened() inline (even if it didn't make any
  difference for gcc 7.5.0), still the right thing to do
---
 sql/handler.cc  | 40 +++++++++++++++++++++++++++-------------
 sql/handler.h   | 10 ++++++++++
 sql/sql_class.h |  7 ++++++-
 3 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/sql/handler.cc b/sql/handler.cc
index 837a7be7ad6..b10cf19f3e3 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -6749,17 +6749,25 @@ extern "C" check_result_t handler_index_cond_check(void* h_arg)
   check_result_t res;
 
   DEBUG_SYNC(thd, "handler_index_cond_check");
-  enum thd_kill_levels abort_at= h->has_rollback() ?
-    THD_ABORT_SOFTLY : THD_ABORT_ASAP;
-  if (thd_kill_level(thd) > abort_at)
-    return CHECK_ABORTED_BY_USER;
 
-  if (h->end_range && h->compare_key2(h->end_range) > 0)
+  enum thd_kill_levels killed= thd_kill_level(thd);
+  if (unlikely(killed != THD_IS_NOT_KILLED))
+  {
+    enum thd_kill_levels abort_at= (h->has_transactions() ?
+                                    THD_ABORT_SOFTLY :
+                                    THD_ABORT_ASAP);
+    if (killed > abort_at)
+      return CHECK_ABORTED_BY_USER;
+  }
+  if (unlikely(h->end_range) && h->compare_key2(h->end_range) > 0)
     return CHECK_OUT_OF_RANGE;
   h->increment_statistics(&SSV::ha_icp_attempts);
-  if ((res= h->pushed_idx_cond->val_int()? CHECK_POS : CHECK_NEG) ==
-      CHECK_POS)
-    h->increment_statistics(&SSV::ha_icp_match);
+  res= CHECK_NEG;
+  if  (h->pushed_idx_cond->val_int())
+  {
+    res= CHECK_POS;
+    h->fast_increment_statistics(&SSV::ha_icp_match);
+  }
   return res;
 }
 
@@ -6783,17 +6791,23 @@ check_result_t handler_rowid_filter_check(void *h_arg)
   {
     THD *thd= h->table->in_use;
     DEBUG_SYNC(thd, "handler_rowid_filter_check");
-    enum thd_kill_levels abort_at= h->has_transactions() ?
-      THD_ABORT_SOFTLY : THD_ABORT_ASAP;
-    if (thd_kill_level(thd) > abort_at)
-      return CHECK_ABORTED_BY_USER;
+
+    enum thd_kill_levels killed= thd_kill_level(thd);
+    if (unlikely(killed != THD_IS_NOT_KILLED))
+    {
+      enum thd_kill_levels abort_at= (h->has_transactions() ?
+                                      THD_ABORT_SOFTLY :
+                                      THD_ABORT_ASAP);
+      if (killed > abort_at)
+        return CHECK_ABORTED_BY_USER;
+    }
 
     if (h->end_range && h->compare_key2(h->end_range) > 0)
       return CHECK_OUT_OF_RANGE;
   }
 
   h->position(tab->record[0]);
-  return h->pushed_rowid_filter->check((char*)h->ref)? CHECK_POS: CHECK_NEG;
+  return h->pushed_rowid_filter->check((char*)h->ref) ? CHECK_POS: CHECK_NEG;
 }
 
 
diff --git a/sql/handler.h b/sql/handler.h
index 6b05da2ca98..2b5e41d1bdd 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3559,6 +3559,10 @@ public:
     table_share= share;
     reset_statistics();
   }
+
+  /*
+    Time for a full table scan of data file
+  */
   virtual double scan_time()
   {
     return ((ulonglong2double(stats.data_file_length) / stats.block_size + 2) *
@@ -4785,7 +4789,13 @@ protected:
     However, engines that implement read_range_XXX() (like MariaRocks)
     or embed other engines (like ha_partition) may need to call these also
   */
+  /*
+    Increment statistics. As a side effect increase accessed_rows_and_keys
+    and checks if lex->limit_rows_examined_cnt is reached
+  */
   inline void increment_statistics(ulong SSV::*offset) const;
+  /* Same as increment_statistics but doesn't increase accessed_rows_and_keys */
+  inline void fast_increment_statistics(ulong SSV::*offset) const;
   inline void decrement_statistics(ulong SSV::*offset) const;
 
 private:
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e13fe9defcb..5e61f94b8ae 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3400,7 +3400,7 @@ public:
     Check if the number of rows accessed by a statement exceeded
     LIMIT ROWS EXAMINED. If so, signal the query engine to stop execution.
   */
-  void check_limit_rows_examined()
+  inline void check_limit_rows_examined()
   {
     if (++accessed_rows_and_keys > lex->limit_rows_examined_cnt)
       set_killed(ABORT_QUERY);
@@ -7408,6 +7408,11 @@ inline void handler::increment_statistics(ulong SSV::*offset) const
   table->in_use->check_limit_rows_examined();
 }
 
+inline void handler::fast_increment_statistics(ulong SSV::*offset) const
+{
+  status_var_increment(table->in_use->status_var.*offset);
+}
+
 inline void handler::decrement_statistics(ulong SSV::*offset) const
 {
   status_var_decrement(table->in_use->status_var.*offset);