summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2017-09-28 16:38:10 +0300
committerMonty <monty@mariadb.org>2017-09-28 16:39:43 +0300
commit04ef45cb5bd69180d90d35cb57a0dab3ab224f60 (patch)
tree4234c900eab6da769a0f7b1d6386067916d5dbdf
parent611b1c76b2e7d9056b04a6d66332989a3f6f3062 (diff)
downloadmariadb-git-04ef45cb5bd69180d90d35cb57a0dab3ab224f60.tar.gz
Adding option to tell that cmp_ref handler call is expensive
- In Spider, calling cmp_ref() can be very expensive. In ha_partition.cc we don't anymore sort rows according to position for the Spider engine. - Removed Spider specific call info(HA_EXTRA_STARTING_ORDERED_INDEX_SCAN) from handle_ordered_index_scan(). It's caused performance issues and does not change results for queries with ORDER BY. - The visible effect of this patch is that for some storage engines, rows may be returned in a different order if there is no ORDER BY clause. - Based in Spiral Patch 052: 052_mariadb-10.2.0.add_partition_skip_pk_sort_for_non_clustered_index.diff MDEV-7748 - The major difference from original patch is that there is no variable to get the old behaviour. - Other things: - Optimized ha_partition::cmp_ref() and cmp_part_ids() to make them simpler and faster. - Changed arguments to cmp_key_part_id() to be same as cmp_key_rowid_part_id to simplify code. Original author: Kentoku SHIBA First reviewer: Jacob Mathew Second reviewer: Michael Widenius
-rw-r--r--sql/ha_partition.cc75
-rw-r--r--sql/ha_partition.h2
-rw-r--r--sql/handler.h4
-rw-r--r--storage/spider/ha_spider.cc1
4 files changed, 27 insertions, 55 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index b43f927aec2..3ce523c63ac 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -89,9 +89,6 @@ static handler *partition_create_handler(handlerton *hton,
static uint partition_flags();
static uint alter_table_flags(uint flags);
-extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
-extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
-
/*
If frm_error() is called then we will use this to to find out what file
extensions exist for the storage engine. This is also used by the default
@@ -5251,17 +5248,11 @@ bool ha_partition::init_record_priority_queue()
/* Initialize priority queue, initialized to reading forward. */
int (*cmp_func)(void *, uchar *, uchar *);
- void *cmp_arg;
- if (!m_using_extended_keys)
- {
+ void *cmp_arg= (void*) this;
+ if (!m_using_extended_keys && !(table_flags() & HA_CMP_REF_IS_EXPENSIVE))
cmp_func= cmp_key_rowid_part_id;
- cmp_arg= (void*)this;
- }
else
- {
cmp_func= cmp_key_part_id;
- cmp_arg= (void*)m_curr_key_info;
- }
DBUG_PRINT("info", ("partition queue_init(1) used_parts: %u", used_parts));
if (init_queue(&m_queue, used_parts, 0, 0, cmp_func, cmp_arg, 0, 0))
{
@@ -5481,22 +5472,13 @@ int ha_partition::index_read_map(uchar *buf, const uchar *key,
/* Compare two part_no partition numbers */
static int cmp_part_ids(uchar *ref1, uchar *ref2)
{
- /* The following was taken from ha_partition::cmp_ref */
- my_ptrdiff_t diff1= ref2[1] - ref1[1];
- my_ptrdiff_t diff2= ref2[0] - ref1[0];
- if (!diff1 && !diff2)
- return 0;
-
- if (diff1 > 0)
- return(-1);
-
- if (diff1 < 0)
- return(+1);
-
- if (diff2 > 0)
- return(-1);
-
- return(+1);
+ uint32 diff2= uint2korr(ref2);
+ uint32 diff1= uint2korr(ref1);
+ if (diff2 > diff1)
+ return -1;
+ if (diff2 < diff1)
+ return 1;
+ return 0;
}
@@ -5505,10 +5487,11 @@ static int cmp_part_ids(uchar *ref1, uchar *ref2)
Provide ordering by (key_value, part_no).
*/
-extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2)
+extern "C" int cmp_key_part_id(void *ptr, uchar *ref1, uchar *ref2)
{
+ ha_partition *file= (ha_partition*)ptr;
int res;
- if ((res= key_rec_cmp(key_p, ref1 + PARTITION_BYTES_IN_POS,
+ if ((res= key_rec_cmp(file->m_curr_key_info, ref1 + PARTITION_BYTES_IN_POS,
ref2 + PARTITION_BYTES_IN_POS)))
{
return res;
@@ -7401,10 +7384,6 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
DBUG_PRINT("enter", ("partition this: %p", this));
- if (!m_using_extended_keys &&
- (error= loop_extra(HA_EXTRA_STARTING_ORDERED_INDEX_SCAN)))
- DBUG_RETURN(error);
-
if (m_pre_calling)
error= handle_pre_scan(reverse_order, m_pre_call_use_parallel);
else
@@ -7589,7 +7568,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
after that read the first entry and copy it to the buffer to return in.
*/
queue_set_max_at_top(&m_queue, reverse_order);
- queue_set_cmp_arg(&m_queue, m_using_extended_keys? m_curr_key_info : (void*)this);
+ queue_set_cmp_arg(&m_queue, (void*) this);
m_queue.elements= j - queue_first_element(&m_queue);
queue_fix(&m_queue);
return_top_record(buf);
@@ -7869,9 +7848,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
DBUG_PRINT("info",("partition m_mrr_range_current->id: %u",
m_mrr_range_current ? m_mrr_range_current->id : 0));
queue_set_max_at_top(&m_queue, FALSE);
- queue_set_cmp_arg(&m_queue, (m_using_extended_keys ?
- m_curr_key_info :
- (void*) this));
+ queue_set_cmp_arg(&m_queue, (void*) this);
m_queue.elements= j;
queue_fix(&m_queue);
return_top_record(buf);
@@ -10034,7 +10011,7 @@ uint ha_partition::min_record_length(uint options) const
int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
{
int cmp;
- my_ptrdiff_t diff1, diff2;
+ uint32 diff1, diff2;
DBUG_ENTER("ha_partition::cmp_ref");
cmp= m_file[0]->cmp_ref((ref1 + PARTITION_BYTES_IN_POS),
@@ -10042,7 +10019,10 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
if (cmp)
DBUG_RETURN(cmp);
- if ((ref1[0] == ref2[0]) && (ref1[1] == ref2[1]))
+ diff2= uint2korr(ref2);
+ diff1= uint2korr(ref1);
+
+ if (diff1 == diff2)
{
/* This means that the references are same and are in same partition.*/
DBUG_RETURN(0);
@@ -10055,22 +10035,7 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
Remove this assert if DB_ROW_ID is changed to be per partition.
*/
DBUG_ASSERT(!m_innodb);
-
- diff1= ref2[1] - ref1[1];
- diff2= ref2[0] - ref1[0];
- if (diff1 > 0)
- {
- DBUG_RETURN(-1);
- }
- if (diff1 < 0)
- {
- DBUG_RETURN(+1);
- }
- if (diff2 > 0)
- {
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(+1);
+ DBUG_RETURN(diff2 > diff1 ? -1 : 1);
}
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 7764eb9192c..4d9302a5179 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -147,6 +147,7 @@ typedef struct st_partition_part_key_multi_range_hld
} PARTITION_PART_KEY_MULTI_RANGE_HLD;
+extern "C" int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
extern "C" int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
class ha_partition :public handler
@@ -1379,5 +1380,6 @@ public:
}
friend int cmp_key_rowid_part_id(void *ptr, uchar *ref1, uchar *ref2);
+ friend int cmp_key_part_id(void *key_p, uchar *ref1, uchar *ref2);
};
#endif /* HA_PARTITION_INCLUDED */
diff --git a/sql/handler.h b/sql/handler.h
index 5dcd27404f6..ab39456c85b 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -160,6 +160,7 @@ enum enum_alter_inplace_result {
*/
#define HA_BINLOG_ROW_CAPABLE (1ULL << 34)
#define HA_BINLOG_STMT_CAPABLE (1ULL << 35)
+
/*
When a multiple key conflict happens in a REPLACE command mysql
expects the conflicts to be reported in the ascending order of
@@ -270,6 +271,9 @@ enum enum_alter_inplace_result {
/* The following is for partition handler */
#define HA_CAN_MULTISTEP_MERGE (1LL << 47)
+/* calling cmp_ref() on the engine is expensive */
+#define HA_CMP_REF_IS_EXPENSIVE (1ULL << 48)
+
/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
#define HA_READ_PREV 2 /* supports ::index_prev */
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index 825df9b9076..c2aafb68de8 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -9193,6 +9193,7 @@ ulonglong ha_spider::table_flags() const
HA_BINLOG_ROW_CAPABLE |
HA_BINLOG_STMT_CAPABLE |
HA_PARTIAL_COLUMN_READ |
+ HA_CMP_REF_IS_EXPENSIVE |
#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
HA_CAN_TABLE_CONDITION_PUSHDOWN |
#endif