diff options
author | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-07-09 01:09:31 +0200 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-07-09 01:09:31 +0200 |
commit | 9edde02ebb908497a7ad12a2c9e28380d1e30531 (patch) | |
tree | 0fc0a4401893f6789b0b486653ec4ce45f0da20b /sql | |
parent | 625ae7185abcfc7042be225d4f8ef77806fc0803 (diff) | |
download | mariadb-git-9edde02ebb908497a7ad12a2c9e28380d1e30531.tar.gz |
Bug#52455: Subpar INSERT ON DUPLICATE KEY UPDATE performance with many partitions
The handler function for reading one row from a specific index
was not optimized in the partitioning handler since it
used the default implementation.
No test case since it is performance only, verified by hand.
sql/ha_partition.cc:
Implemented a optimized version of index_read_idx_map
for the case when find flag == HA_READ_KEY_EXACT,
which is the common case.
sql/ha_partition.h:
Declared ha_partition::index_read_idx_map
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_partition.cc | 52 | ||||
-rw-r--r-- | sql/ha_partition.h | 9 |
2 files changed, 61 insertions, 0 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 60722f0100e..a87c7fbf7b8 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4220,6 +4220,58 @@ int ha_partition::index_read_last_map(uchar *buf, const uchar *key, /* + Optimization of the default implementation to take advantage of dynamic + partition pruning. +*/ +int ha_partition::index_read_idx_map(uchar *buf, uint index, + const uchar *key, + key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ + int error= HA_ERR_KEY_NOT_FOUND; + DBUG_ENTER("ha_partition::index_read_idx_map"); + + if (find_flag == HA_READ_KEY_EXACT) + { + uint part; + m_start_key.key= key; + m_start_key.keypart_map= keypart_map; + m_start_key.flag= find_flag; + m_start_key.length= calculate_key_len(table, index, m_start_key.key, + m_start_key.keypart_map); + + get_partition_set(table, buf, index, &m_start_key, &m_part_spec); + + /* How can it be more than one partition with the current use? */ + DBUG_ASSERT(m_part_spec.start_part == m_part_spec.end_part); + + for (part= m_part_spec.start_part; part <= m_part_spec.end_part; part++) + { + if (bitmap_is_set(&(m_part_info->used_partitions), part)) + { + error= m_file[part]->index_read_idx_map(buf, index, key, + keypart_map, find_flag); + if (error != HA_ERR_KEY_NOT_FOUND && + error != HA_ERR_END_OF_FILE) + break; + } + } + } + else + { + /* + If not only used with READ_EXACT, we should investigate if possible + to optimize for other find_flag's as well. + */ + DBUG_ASSERT(0); + /* fall back on the default implementation */ + error= handler::index_read_idx_map(buf, index, key, keypart_map, find_flag); + } + DBUG_RETURN(error); +} + + +/* Read next record in a forward index scan SYNOPSIS diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 9f6d9e0a5ba..d8872d37a09 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -448,6 +448,15 @@ public: virtual int index_init(uint idx, bool sorted); virtual int index_end(); + /** + @breif + Positions an index cursor to the index specified in the hanlde. Fetches the + row if available. If the key value is null, begin at first key of the + index. + */ + virtual int index_read_idx_map(uchar *buf, uint index, const uchar *key, + key_part_map keypart_map, + enum ha_rkey_function find_flag); /* These methods are used to jump to next or previous entry in the index scan. There are also methods to jump to first and last entry. |