[ 
https://issues.apache.org/jira/browse/TRAFODION-25?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14945098#comment-14945098
 ] 

ASF GitHub Bot commented on TRAFODION-25:
-----------------------------------------

Github user nonstop-qfchen commented on a diff in the pull request:

    https://github.com/apache/incubator-trafodion/pull/102#discussion_r41270518
  
    --- 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;
    --- End diff --
    
    should we assert that getProbesForceSynchronousAccessFlag() is FALSE here?


> 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)

Reply via email to