[
https://issues.apache.org/jira/browse/TRAFODION-25?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14944149#comment-14944149
]
ASF GitHub Bot commented on TRAFODION-25:
-----------------------------------------
Github user zellerh commented on a diff in the pull request:
https://github.com/apache/incubator-trafodion/pull/102#discussion_r41206233
--- Diff: core/sql/optimizer/ScmCostMethod.cpp ---
@@ -3632,6 +3632,561 @@
CostMethodMergeUnion::scmComputeOperatorCostInternal(RelExpr *op,
//<pb>
+// -------------------------------------------------------------------
+// Cost methods for write DML operations
+// -------------------------------------------------------------------
+
+
+// -------------------------------------------------------------------
+// This method is a stub for obsolete old cost model
+// -------------------------------------------------------------------
+Cost*
+CostMethodHbaseUpdateOrDelete::computeOperatorCostInternal(RelExpr* op,
+ const Context * context,
+ Lng32& countOfStreams)
+{
+ CMPASSERT(false); // should never be called
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+// CostMethodHbaseUpdateOrDelete::allKeyColumnsHaveHistogramStatistics()
+//
+// Returns TRUE if all key columns have histograms, FALSE if not.
+// -----------------------------------------------------------------------
+NABoolean
CostMethodHbaseUpdateOrDelete::allKeyColumnsHaveHistogramStatistics(
+ const IndexDescHistograms & histograms,
+ const IndexDesc * CIDesc
+ ) const
+{
+ // Check if all key columns have histogram statistics
+ NABoolean statsForAllKeyCols = TRUE;
+ for ( CollIndex j = 0; j < CIDesc->getIndexKey().entries(); j++ )
+ {
+ if (histograms.isEmpty())
+ {
+ statsForAllKeyCols = FALSE;
+ break;
+ }
+ else if (!histograms.getColStatsPtrForColumn((CIDesc->getIndexKey())
[j]))
+ {
+ // If we get a null pointer when we try to retrieve a
+ // ColStats for a column of this table, then no histogram
+ // data was created for that column.
+ statsForAllKeyCols = FALSE;
+ break;
+ }
+ }
+
+ return statsForAllKeyCols;
+} //
CostMethodHbaseUpdateOrDelete::allKeyColumnsHaveHistogramStatistics()
+
+// -----------------------------------------------------------------------
+//
CostMethodHbaseUpdateOrDelete::numRowsToScanWhenAllKeyColumnsHaveHistograms()
+//
+// Returns an estimate of the number of rows that will be scanned as a
+// result of applying key predicates. Assumes that histograms exist for
+// all key columns.
+// -----------------------------------------------------------------------
+#pragma nowarn(262) // warning elimination
+CostScalar
+CostMethodHbaseUpdateOrDelete::numRowsToScanWhenAllKeyColumnsHaveHistograms(
+ IndexDescHistograms & histograms,
+ const ColumnOrderList & keyPredsByCol,
+ const CostScalar & activePartitions,
+ const IndexDesc * CIDesc
+ ) const
+{
+
+ // Determine if there are single subset predicates:
+ CollIndex singleSubsetPrefixOrder;
+ NABoolean itIsSingleSubset =
+ keyPredsByCol.getSingleSubsetOrder( singleSubsetPrefixOrder );
+
+ NABoolean thereAreSingleSubsetPreds = FALSE;
+ if ( singleSubsetPrefixOrder > 0 )
+ {
+ thereAreSingleSubsetPreds = TRUE;
+ }
+ else
+ {
+ // singleSubsetPrefixOrder==0 means either there
+ // is an equal, an IN, or there are no key preds in the
+ // first column.
+ // singleSubsetPrefixOrder==0 AND itIsSingleSubset
+ // means there is an EQUAL or there are no key preds
+ // in the first column, check for existance of
+ // predicates in this case:
+ if ( itIsSingleSubset // this FALSE for an IN predicate
+ AND keyPredsByCol[0] != NULL
+ )
+ {
+ thereAreSingleSubsetPreds = TRUE;
+ }
+ }
+
+
+ CMPASSERT(NOT histograms.isEmpty());
+
+ if ( thereAreSingleSubsetPreds )
+ {
+ // ---------------------------------------------------------
+ // There are some key predicates, so apply them
+ // to the histograms and get the total rows:
+ // ---------------------------------------------------------
+
+ // Get all the key preds for the key columns up to the first
+ // key column with no key preds
+ ValueIdSet singleSubsetPrefixPredicates;
+ NABoolean conflict = FALSE;
+ for ( CollIndex i = 0; i <= singleSubsetPrefixOrder; i++ )
+ {
+
+ const ValueIdSet *predsPtr = keyPredsByCol[i];
+ CMPASSERT( predsPtr != NULL ); // it must contain preds
+ singleSubsetPrefixPredicates.insert( *predsPtr );
+
+ } // for every key col in the sing. subset prefix
+
+ // Apply those key predicates that reference key columns
+ // before the first missing key to the histograms:
+ const SelectivityHint * selHint =
CIDesc->getPrimaryTableDesc()->getSelectivityHint();
+ const CardinalityHint * cardHint =
CIDesc->getPrimaryTableDesc()->getCardinalityHint();
+
+ RelExpr * dummyExpr = new (STMTHEAP) RelExpr(ITM_FIRST_ITEM_OP,
+ NULL,
+ NULL,
+ STMTHEAP);
+
+ histograms.applyPredicates( singleSubsetPrefixPredicates, *dummyExpr,
selHint, cardHint);
+
+ } // if there are key predicates
+
+ // If there is no key predicates, a full table scan will be generated.
+ // Otherwise, key predicates will be applied to the histograms.
+ // Now, compute the number of rows after key preds are applied,
+ // and accounting for asynchronous parallelism:
+ CostScalar numRowsToScan =
+ ((histograms.getRowCount()/activePartitions).getCeiling()).minCsOne();
+
+ return numRowsToScan;
+} //
CostMethodHbaseUpdateOrDelete::numRowsToScanWhenAllKeyColumnsHaveHistograms()
+#pragma warn(262) // warning elimination
+
+// -----------------------------------------------------------------------
+// CostMethodHbaseUpdateOrDelete::computeIOCostsForCursorOperation().
+// -----------------------------------------------------------------------
+void CostMethodHbaseUpdateOrDelete::computeIOCostsForCursorOperation(
+ CostScalar & randomIOs, // out
+ CostScalar & sequentialIOs, // out
+ const IndexDesc * CIDesc,
+ const CostScalar & numRowsToScan,
+ NABoolean probesInOrder
+ ) const
+{
+ const CostScalar indexLevels = CIDesc->getIndexLevels();
+ const CostScalar & kbPerBlock = CIDesc->getBlockSizeInKb();
+ const CostScalar rowsPerBlock =
+ ((kbPerBlock * csOneKiloBytes) /
+ CIDesc->getNAFileSet()->getRecordLength()).getFloor();
+ CostScalar totalIndexBlocks(csZero);
+
+ if (probesInOrder)
+ {
+ // If the probes are in order, assume that each successive
+ // probe refers to the next record in the table, i.e. the
+ // probes are "highly inclusive", or in other words, there
+ // are no gaps in the records to be updated. So, assuming
+ // this, the number of blocks that need to be read is
+ // the # of probes divided by the rows per block. This is
+ // guaranteed to be correct if we are updating most of the
+ // rows, we can only go wrong if we are updating a small
+ // number of dispersed rows. This seems unlikely, and anyway
+ // even if it's true we won't be that far off. If the rows
+ // are highly inclusive, we could also assume that since the
+ // blocks will be contiguous that there will only by one seek.
+ // But, we'd be way off in the case where the assumption
+ // doesn't hold so we won't do it for now. What we need is
+ // some way to determine the "inclusiveness factor".
+ sequentialIOs = (numRowsToScan / rowsPerBlock).getCeiling();
+ // The # of index blocks to read is based on the number of data
+ // blocks that must be read
+ totalIndexBlocks =
+ CIDesc->getEstimatedIndexBlocksLowerBound(sequentialIOs);
+ randomIOs = totalIndexBlocks;
+ }
+ else // probes not in order
+ {
+ // Assume all IOs are random. This is a bit pessimistic
+ // because at some point much of the file will be in cache,
+ // so one could argue that as the number of rows updated
+ // or deleted grows large the number of random IOs should
+ // decrease. We'll leave that to future work.
+ sequentialIOs = csZero;
+ totalIndexBlocks =
+ CIDesc->getEstimatedIndexBlocksLowerBound(numRowsToScan);
+ randomIOs = numRowsToScan + totalIndexBlocks;
+ }
+
+} // CostMethodHbaseUpdateOrDelete::computeIOCostsForCursorOperation()
+
+
+
+// ----QUICKSEARCH FOR HbaseUpdate........................................
+
+/**********************************************************************/
+/* */
+/* CostMethodHbaseUpdate */
+/* */
+/**********************************************************************/
+
+//*******************************************************************
+// This method computes the cost vector of the HbaseUpdate operation
+//*******************************************************************
+Cost*
+CostMethodHbaseUpdate::scmComputeOperatorCostInternal(RelExpr* op,
+ const PlanWorkSpace* pws,
+ Lng32& countOfStreams)
+{
+ // TODO: Write this method; the line below is a stub
+ return CostMethod::scmComputeOperatorCostInternal(op,pws,countOfStreams);
+}
+
+// ----QUICKSEARCH FOR HbaseDelete........................................
+
+/**********************************************************************/
+/* */
+/* CostMethodHbaseDelete */
+/* */
+/**********************************************************************/
+
+//*******************************************************************
+// This method computes the cost vector of the HbaseDelete operation
+//*******************************************************************
+Cost*
+CostMethodHbaseDelete::scmComputeOperatorCostInternal(RelExpr* op,
+ const PlanWorkSpace* pws,
+ Lng32& countOfStreams)
+{
+ const Context * myContext = pws->getContext();
+
+ cacheParameters(op,myContext);
+ estimateDegreeOfParallelism();
+
+ const InputPhysicalProperty* ippForMe =
+ myContext->getInputPhysicalProperty();
+
+ // -----------------------------------------
+ // Save off estimated degree of parallelism.
+ // -----------------------------------------
+ countOfStreams = countOfStreams_;
+
+ HbaseDelete* delOp = (HbaseDelete *)op; // downcast
+
+ CMPASSERT(partFunc_ != NULL);
+ CostScalar activePartitions =
+ (CostScalar)
+ (((NodeMap *)(partFunc_->getNodeMap()))->getNumActivePartitions());
+ const IndexDesc* CIDesc = delOp->getIndexDesc();
+ const CostScalar & recordSizeInKb = CIDesc->getRecordSizeInKb();
+
+ CostScalar tuplesProcessed(csZero);
+ CostScalar tuplesProduced(csZero);
+ CostScalar tuplesSent(csZero); // we use tuplesSent to model sending
rowIDs to Hbase
+ CostScalar randomIOs(csZero);
+ CostScalar sequentialIOs(csZero);
+
+ CostScalar countOfAsynchronousStreams = activePartitions;
+
+ // figure out if the probes are in order - if they are, then when
+ // scanning, I/O will tend to be sequential
+
+ NABoolean probesInOrder = FALSE;
+ if (ippForMe != NULL) // input physical properties exist?
+ {
+ // See if the probes are in order.
+
+ // For delete, a partial order is ok.
+ NABoolean partiallyInOrderOK = TRUE;
+ NABoolean probesForceSynchronousAccess = FALSE;
+ ValueIdList targetSortKey = CIDesc->getOrderOfKeyValues();
+ ValueIdSet sourceCharInputs =
+ delOp->getGroupAttr()->getCharacteristicInputs();
+
+ ValueIdSet targetCharInputs;
+ // The char inputs are still in terms of the source. Map them to the
target.
+ // Note: The source char outputs in the ipp have already been mapped to
+ // the target. CharOutputs are a set, meaning they do not have
duplicates
+ // But we could have cases where two columns of the target are matched
to the
--- End diff --
The updateToSelectMap() is really just a helper structure and its contents
should not be examined to make these kind of decisions. I would suggest
deleting anything that references bottomValues, bottomValuesSet and
useListInsteadOfSet and to do the rewrite that's shown on line 3960. Sorry if I
missed some complication that this code is meant to address.
> Insert, delete and update operators should use specialized cost method
> -----------------------------------------------------------------------
>
> Key: TRAFODION-25
> URL: https://issues.apache.org/jira/browse/TRAFODION-25
> Project: Apache Trafodion
> Issue Type: Bug
> Reporter: Qifan Chen
> Assignee: David Wayne Birdsall
> Labels: performance
>
> In Trafodion, insert, delete and update operators do not use a specialized
> cost method that model the true operation involved.
> As a result, these operators can be assigned a zero cost and the query plan
> may not be optimal. In one example, a delete query against a partitioned
> table may get a serial plan.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)