@@ -203,6 +203,9 @@ func getCostedIndexScan(ctx *sql.Context, statsProv sql.StatsProvider, rt sql.Ta
203203 if ! ok {
204204 stat , err = uniformDistStatisticsForIndex (ctx , statsProv , iat , idx )
205205 }
206+ if err != nil {
207+ return nil , nil , nil , err
208+ }
206209 err := c .cost (root , stat , idx )
207210 if err != nil {
208211 return nil , nil , nil , err
@@ -534,6 +537,16 @@ func (c *indexCoster) updateBest(s sql.Statistic, hist []sql.HistogramBucket, fd
534537 return
535538 }
536539
540+ // If one index uses a superset of the filters of the other, we should always pick the superset.
541+ if c .bestFilters .SubsetOf (filters ) {
542+ update = true
543+ return
544+ }
545+
546+ if filters .SubsetOf (c .bestFilters ) {
547+ return
548+ }
549+
537550 bestKey , bok := best .StrictKey ()
538551 cmpKey , cok := cmp .StrictKey ()
539552 if cok && ! bok {
@@ -575,6 +588,10 @@ func (c *indexCoster) updateBest(s sql.Statistic, hist []sql.HistogramBucket, fd
575588 return
576589 }
577590
591+ if filters .Len () < c .bestFilters .Len () {
592+ return
593+ }
594+
578595 if s .ColSet ().Len ()- filters .Len () < c .bestStat .ColSet ().Len ()- c .bestFilters .Len () {
579596 // prefer 1 range filter over 1 column index (1 - 1 = 0)
580597 // vs. 1 range filter over 2 column index (2 - 1 = 1)
@@ -1237,11 +1254,6 @@ func (c *indexCoster) costIndexScanAnd(ctx *sql.Context, filter *iScanAnd, s sql
12371254 conjFDs = conj .getFds ()
12381255 }
12391256
1240- if exact .Len ()+ conj .applied .Len () == filter .childCnt () {
1241- // matched all filters
1242- return conj .hist , conjFDs , sql .NewFastIntSet (int (filter .id )), conj .missingPrefix , nil
1243- }
1244-
12451257 return conj .hist , conjFDs , exact .Union (conj .applied ), conj .missingPrefix , nil
12461258}
12471259
0 commit comments