code: func (ds *DataSource) skylinePruning(prop *property.PhysicalProperty) []*candidatePath {
  	candidates := make([]*candidatePath, 0, 4)
  	for _, path := range ds.possibleAccessPaths {
  		// if we already know the range of the scan is empty, just return a TableDual
  		if len(path.ranges) == 0 && !ds.ctx.GetSessionVars().StmtCtx.UseCache {
  			return []*candidatePath{{path: path}}
  		}
  		var currentCandidate *candidatePath
  		if path.isTablePath {
  			currentCandidate = ds.getTableCandidate(path, prop)
  		} else if len(path.accessConds) > 0 || !prop.IsEmpty() || path.forced {
  			// We will use index to generate physical plan if:
  			// this path's access cond is not nil or
  			// we have prop to match or
  			// this index is forced to choose.
  			currentCandidate = ds.getIndexCandidate(path, prop)
  		} else {
  			continue
  		}
  		pruned := false
  		for i := len(candidates) - 1; i >= 0; i-- {
  			result := compareCandidates(candidates[i], currentCandidate)
  			if result == 1 {
  				pruned = true
  				// We can break here because the current candidate cannot prune others anymore.
  				break
  			} else if result == -1 {
  				candidates = append(candidates[:i], candidates[i+1:]...)
  			}
  		}
  		if !pruned {
  			candidates = append(candidates, currentCandidate)
  		}
  	}
  	return candidates
  }
docs: // skylinePruning prunes access paths according to different factors. An access path can be pruned only if
  // there exists a path that is not worse than it at all factors and there is at least one better factor.