-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
planner, statistics: fix the inconsistent est when table has no stats #52427
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,11 +195,21 @@ func (c *columnStatsUsageCollector) addHistNeededColumns(ds *DataSource) { | |
colIDSet := intset.NewFastIntSet() | ||
|
||
for _, col := range columns { | ||
// If the column is plan-generated one, Skip it. | ||
// TODO: we may need to consider the ExtraHandle. | ||
if col.ID < 0 { | ||
continue | ||
} | ||
tblColID := model.TableItemID{TableID: ds.physicalTableID, ID: col.ID, IsIndex: false} | ||
colIDSet.Insert(int(col.ID)) | ||
c.histNeededCols[tblColID] = true | ||
} | ||
for _, col := range ds.Columns { | ||
// If the column is plan-generated one, Skip it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto. |
||
// TODO: we may need to consider the ExtraHandle. | ||
if col.ID < 0 { | ||
continue | ||
} | ||
if !colIDSet.Has(int(col.ID)) && !col.Hidden { | ||
tblColID := model.TableItemID{TableID: ds.physicalTableID, ID: col.ID, IsIndex: false} | ||
if _, ok := c.histNeededCols[tblColID]; ok { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -572,7 +572,9 @@ func CleanFakeItemsForShowHistInFlights(statsCache statstypes.StatsCache) int { | |
if item.IsIndex { | ||
_, loadNeeded = tbl.IndexIsLoadNeeded(item.ID) | ||
} else { | ||
_, loadNeeded = tbl.ColumnIsLoadNeeded(item.ID, true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We keep the async load unchanged. Wait for later patch to handle it. |
||
var analyzed bool | ||
_, loadNeeded, analyzed = tbl.ColumnIsLoadNeeded(item.ID, true) | ||
loadNeeded = loadNeeded && analyzed | ||
} | ||
if !loadNeeded { | ||
statistics.HistogramNeededItems.Delete(item) | ||
|
@@ -589,8 +591,8 @@ func loadNeededColumnHistograms(sctx sessionctx.Context, statsCache statstypes.S | |
return nil | ||
} | ||
var colInfo *model.ColumnInfo | ||
_, loadNeeded := tbl.ColumnIsLoadNeeded(col.ID, true) | ||
if !loadNeeded { | ||
_, loadNeeded, analyzed := tbl.ColumnIsLoadNeeded(col.ID, true) | ||
if !loadNeeded || !analyzed { | ||
statistics.HistogramNeededItems.Delete(col) | ||
return nil | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -629,25 +629,37 @@ func (t *Table) GetStatsHealthy() (int64, bool) { | |
// The Column should be visible in the table and really has analyzed statistics in the stroage. | ||
// Also, if the stats has been loaded into the memory, we also don't need to load it. | ||
// We return the Column together with the checking result, to avoid accessing the map multiple times. | ||
func (t *Table) ColumnIsLoadNeeded(id int64, fullLoad bool) (*Column, bool) { | ||
// The first bool is whether we have it in memory. The second bool is whether this column has stats in the system table or not. | ||
func (t *Table) ColumnIsLoadNeeded(id int64, fullLoad bool) (*Column, bool, bool) { | ||
if t.Pseudo { | ||
return nil, false, false | ||
} | ||
col, ok := t.Columns[id] | ||
hasAnalyzed := t.ColAndIdxExistenceMap.HasAnalyzed(id, false) | ||
|
||
// If it's not analyzed yet. Don't need to load it. | ||
// If it's not analyzed yet. | ||
if !hasAnalyzed { | ||
return nil, false | ||
// If we don't have it in memory, we create a fake hist for pseudo estimation (see handleOneItemTask()). | ||
if !ok { | ||
// If we don't have this column. We skip it. | ||
// It's something ridiculous. But it's possible that the stats don't have some ColumnInfo. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this means this column has stats but doesn't have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Such that |
||
// We need to find a way to maintain it more correctly. | ||
return nil, t.ColAndIdxExistenceMap.Has(id, false), false | ||
} | ||
// Otherwise we don't need to load it. | ||
return nil, false, false | ||
} | ||
|
||
// Restore the condition from the simplified form: | ||
// 1. !ok && hasAnalyzed => need load | ||
// 2. ok && hasAnalyzed && fullLoad && !col.IsFullLoad => need load | ||
// 3. ok && hasAnalyzed && !fullLoad && !col.statsInitialized => need load | ||
if !ok || (fullLoad && !col.IsFullLoad()) || (!fullLoad && !col.statsInitialized) { | ||
return col, true | ||
return col, true, true | ||
} | ||
|
||
// Otherwise don't need load it. | ||
return col, false | ||
return col, false, true | ||
} | ||
|
||
// IndexIsLoadNeeded checks whether the index needs trigger the async/sync load. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "plan-generated" mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such that ID=-1 means ExtraHandleCol