3399 Ole John Aske 2011-10-25
Integrated pushed join execution into new MRR interface.
modified:
mysql-test/suite/ndb/r/ndb_join_pushdown.result
sql/ha_ndbcluster.cc
3398 Ole John Aske 2011-10-21
Reverted part of previous fix: Increased execute count should not
be expected after all when 'Read Before Write Removal' now has
been implemented.
modified:
mysql-test/suite/ndb/t/ndb_bulk_delete.test
=== modified file 'mysql-test/suite/ndb/r/ndb_join_pushdown.result'
--- a/mysql-test/suite/ndb/r/ndb_join_pushdown.result 2011-10-18 10:43:35 +0000
+++ b/mysql-test/suite/ndb/r/ndb_join_pushdown.result 2011-10-25 08:09:27 +0000
@@ -4028,15 +4028,15 @@ and new_count.counter_name <> 'LOCAL_REA
and new_count.counter_name <> 'REMOTE_READS_SENT';
counter_name new_count.val - old_count.val
CONST_PRUNED_RANGE_SCANS_RECEIVED 0
-LOCAL_RANGE_SCANS_SENT 0
+LOCAL_RANGE_SCANS_SENT 2
LOCAL_TABLE_SCANS_SENT 2
PRUNED_RANGE_SCANS_RECEIVED 0
-RANGE_SCANS_RECEIVED 0
-READS_NOT_FOUND 1
+RANGE_SCANS_RECEIVED 2
+READS_NOT_FOUND 2
READS_RECEIVED 1
REMOTE_RANGE_SCANS_SENT 0
-SCAN_BATCHES_RETURNED 2
-SCAN_ROWS_RETURNED 5
+SCAN_BATCHES_RETURNED 4
+SCAN_ROWS_RETURNED 8
TABLE_SCANS_RECEIVED 2
select 'READS_SENT', sum(new_count.val - old_count.val)
from new_count, old_count
@@ -4044,7 +4044,7 @@ where new_count.counter_name = old_count
and (new_count.counter_name = 'LOCAL_READS_SENT'
or new_count.counter_name = 'REMOTE_READS_SENT');
READS_SENT sum(new_count.val - old_count.val)
-READS_SENT 5
+READS_SENT 7
drop table old_count;
drop table new_count;
drop table t1;
@@ -5487,8 +5487,8 @@ counter_name spj_counts_at_end.val - spj
CONST_PRUNED_RANGE_SCANS_RECEIVED 6
LOCAL_TABLE_SCANS_SENT 250
PRUNED_RANGE_SCANS_RECEIVED 25
-RANGE_SCANS_RECEIVED 703
-READS_RECEIVED 53
+RANGE_SCANS_RECEIVED 726
+READS_RECEIVED 58
TABLE_SCANS_RECEIVED 250
drop table spj_counts_at_startup;
drop table spj_counts_at_end;
@@ -5497,11 +5497,11 @@ scan_count_derived
pruned_scan_count
8
sorted_scan_count
-34
+35
pushed_queries_defined
401
pushed_queries_dropped
-6
+9
pushed_queries_executed
-529
+547
set ndb_join_pushdown = @save_ndb_join_pushdown;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2011-10-21 12:52:20 +0000
+++ b/sql/ha_ndbcluster.cc 2011-10-25 08:09:27 +0000
@@ -14668,8 +14668,6 @@ read_multi_needs_scan(NDB_INDEX_TYPE cur
The implementation is copied from handler::multi_range_read_info_const.
The only difference is that NDB-MRR cannot handle blob columns or keys
with NULLs for unique indexes. We disable MRR for those cases.
- As Pushed join execution has not yet been integrated into NDB-MRR,
- we also disable MRR for those.
NOTES
See NOTES for handler::multi_range_read_info_const().
@@ -14730,9 +14728,7 @@ ha_ndbcluster::multi_range_read_info_con
{
if (uses_blob_value(table->read_set) ||
((get_index_type(keyno) == UNIQUE_INDEX &&
- has_null_in_unique_index(keyno)) && null_ranges)
- || (m_pushed_join_operation==PUSHED_ROOT &&
- !m_disable_pushed_join))
+ has_null_in_unique_index(keyno)) && null_ranges))
{
/* Use default MRR implementation */
*flags|= HA_MRR_USE_DEFAULT_IMPL;
@@ -14867,6 +14863,9 @@ int ha_ndbcluster::multi_range_read_init
|| bufsize < multi_range_fixed_size(1) +
multi_range_max_entry(get_index_type(active_index),
table_share->reclength)
+ || (m_pushed_join_operation==PUSHED_ROOT &&
+ !m_disable_pushed_join &&
+ !m_pushed_join_member->get_query_def().isScanQuery())
|| m_delete_cannot_batch || m_update_cannot_batch)
{
m_disable_multi_read= TRUE;
@@ -14992,7 +14991,10 @@ int ha_ndbcluster::multi_range_start_ret
if (range_no >= max_range)
break;
my_bool need_scan=
- read_multi_needs_scan(cur_index_type, key_info, &mrr_cur_range);
+ read_multi_needs_scan(cur_index_type, key_info, &mrr_cur_range) ||
+ // Pushed joins restricted to ordered range scan in mrr
+ (m_pushed_join_operation==PUSHED_ROOT &&
+ m_pushed_join_member->get_query_def().isScanQuery());
if (row_buf + multi_range_entry_size(!need_scan, reclength) > end_of_buffer)
break;
if (need_scan)
@@ -15069,7 +15071,25 @@ int ha_ndbcluster::multi_range_start_ret
DBUG_PRINT("info", ("any_real_read= TRUE"));
/* Create the scan operation for the first scan range. */
- if (!m_multi_cursor)
+ if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan,
+ active_index,
+ !m_active_query && mrr_is_output_sorted))
+ {
+ DBUG_ASSERT(!m_read_before_write_removal_used);
+ if (!m_active_query)
+ {
+ const int error= create_pushed_join();
+ if (unlikely(error))
+ DBUG_RETURN(error);
+
+ NdbQuery* const query= m_active_query;
+ if (mrr_is_output_sorted &&
+ query->getQueryOperation((uint)PUSHED_ROOT)->setOrdering(NdbQueryOptions::ScanOrdering_ascending))
+ ERR_RETURN(query->getNdbError());
+ }
+ } // check_if_pushable()
+
+ else if (!m_multi_cursor)
{
/* Do a multi-range index scan for ranges not done by primary/unique key. */
NdbScanOperation::ScanOptions options;
@@ -15147,12 +15167,24 @@ int ha_ndbcluster::multi_range_start_ret
&mrr_cur_range.start_key, &mrr_cur_range.end_key, 0);
bound.range_no= range_no;
- if (m_multi_cursor->setBound(m_index[active_index].ndb_record_key,
- bound,
- ndbPartSpecPtr, // Only for user-def tables
- sizeof(Ndb::PartitionSpec)))
+ const NdbRecord *key_rec= m_index[active_index].ndb_record_key;
+ if (m_active_query)
+ {
+ DBUG_PRINT("info", ("setBound:%d, for pushed join", bound.range_no));
+ if (m_active_query->setBound(key_rec, &bound))
+ {
+ ERR_RETURN(trans->getNdbError());
+ }
+ }
+ else
{
- ERR_RETURN(trans->getNdbError());
+ if (m_multi_cursor->setBound(m_index[active_index].ndb_record_key,
+ bound,
+ ndbPartSpecPtr, // Only for user-def tables
+ sizeof(Ndb::PartitionSpec)))
+ {
+ ERR_RETURN(trans->getNdbError());
+ }
}
multi_range_entry_type(row_buf)= enum_ordered_range;
@@ -15201,17 +15233,60 @@ int ha_ndbcluster::multi_range_start_ret
ppartitionId=&partitionId;
}
- if (!(op= pk_unique_index_read_key(active_index,
- mrr_cur_range.start_key.key,
- multi_range_row(row_buf), lm,
- ppartitionId)))
- ERR_RETURN(trans->getNdbError());
+ /**
+ * 'Pushable codepath' is incomplete and expected not
+ * to be produced as make_join_pushed() handle
+ * AT_MULTI_UNIQUE_KEY as non-pushable.
+ */
+ if (m_pushed_join_operation==PUSHED_ROOT &&
+ !m_disable_pushed_join &&
+ !m_pushed_join_member->get_query_def().isScanQuery())
+ {
+ DBUG_ASSERT(false); // FIXME: Incomplete code, should not be executed
+ DBUG_ASSERT(lm == NdbOperation::LM_CommittedRead);
+ const int error= pk_unique_index_read_key_pushed(active_index,
+ mrr_cur_range.start_key.key,
+ ppartitionId);
+ if (unlikely(error))
+ DBUG_RETURN(error);
+ }
+ else
+ {
+ if (m_pushed_join_operation == PUSHED_ROOT)
+ {
+ DBUG_PRINT("info", ("Cannot push join due to incomplete implementation."));
+ m_thd_ndb->m_pushed_queries_dropped++;
+ }
+ if (!(op= pk_unique_index_read_key(active_index,
+ mrr_cur_range.start_key.key,
+ multi_range_row(row_buf), lm,
+ ppartitionId)))
+ ERR_RETURN(trans->getNdbError());
+ }
}
oplist[num_keyops++]= op;
row_buf= multi_range_next_entry(row_buf, reclength);
}
}
+ if (m_active_query != NULL &&
+ m_pushed_join_member->get_query_def().isScanQuery())
+ {
+ m_thd_ndb->m_scan_count++;
+ if (mrr_is_output_sorted)
+ {
+ m_thd_ndb->m_sorted_scan_count++;
+ }
+
+ bool prunable= false;
+ if (unlikely(m_active_query->isPrunable(prunable) != 0))
+ ERR_RETURN(m_active_query->getNdbError());
+ if (prunable)
+ m_thd_ndb->m_pruned_scan_count++;
+
+ DBUG_PRINT("info", ("Is MRR scan-query pruned to 1 partition? :%u", prunable));
+ DBUG_ASSERT(!m_multi_cursor);
+ }
if (m_multi_cursor)
{
DBUG_PRINT("info", ("Is MRR scan pruned to 1 partition? :%u",
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk-cluster branch (ole.john.aske:3398 to 3399) | Ole John Aske | 25 Oct |