Documentation
¶
Index ¶
- func Close(e Executor) (err error)
- func NewFirstChunk(e Executor) *chunk.Chunk
- func Next(ctx context.Context, e Executor, req *chunk.Chunk) (err error)
- func Open(ctx context.Context, e Executor) (err error)
- func RetTypes(e Executor) []*types.FieldType
- func TryNewCacheChunk(e Executor) *chunk.Chunk
- type AdaptiveLimitConfig
- type AdaptiveLimitController
- func (c *AdaptiveLimitController) AbortLookup(handles int)
- func (c *AdaptiveLimitController) CommitOuter(reserved, fetched int)
- func (c *AdaptiveLimitController) CompleteLookup(reserved, handles, rows int)
- func (c *AdaptiveLimitController) ObserveJoinProgress(consumedRows, outputRows int)
- func (c *AdaptiveLimitController) ReserveLookup(ctx context.Context, maxHandles int) (int, bool, error)
- func (c *AdaptiveLimitController) ReserveOuter(ctx context.Context, maxRows int) (int, bool, error)
- func (c *AdaptiveLimitController) Reset()
- func (c *AdaptiveLimitController) Snapshot() AdaptiveLimitSnapshot
- func (c *AdaptiveLimitController) Stop()
- func (c *AdaptiveLimitController) SuggestedBatchSize(ceiling int) int
- type AdaptiveLimitSnapshot
- type BaseExecutor
- func (e *BaseExecutor) AllChildren() []Executor
- func (e *BaseExecutor) Children(idx int) Executor
- func (e *BaseExecutor) ChildrenLen() int
- func (e *BaseExecutor) Ctx() sessionctx.Context
- func (e *BaseExecutor) EmptyChildren() bool
- func (e *BaseExecutor) GetSchema() *expression.Schema
- func (e *BaseExecutor) GetSysSession() (sessionctx.Context, error)
- func (e *BaseExecutor) HandleSQLKillerSignal() error
- func (e *BaseExecutor) ID() int
- func (e *BaseExecutor) InitCap() int
- func (e *BaseExecutor) MaxChunkSize() int
- func (e *BaseExecutor) NewChunk() *chunk.Chunk
- func (e *BaseExecutor) NewChunkWithCapacity(fields []*types.FieldType, capacity int, maxCachesize int) *chunk.Chunk
- func (e *BaseExecutor) RegisterSQLAndPlanInExecForTopProfiling()
- func (e *BaseExecutor) ReleaseSysSession(ctx context.Context, sctx sessionctx.Context)
- func (e *BaseExecutor) RetFieldTypes() []*types.FieldType
- func (e *BaseExecutor) RuntimeStats() *execdetails.BasicRuntimeStats
- func (e *BaseExecutor) Schema() *expression.Schema
- func (e *BaseExecutor) SetAllChildren(children []Executor)
- func (e *BaseExecutor) SetChildren(idx int, ex Executor)
- func (e *BaseExecutor) SetInitCap(c int)
- func (e *BaseExecutor) SetMaxChunkSize(size int)
- func (e *BaseExecutor) UpdateDeltaForTableID(id int64)
- type BaseExecutorV2
- func (e *BaseExecutorV2) AllChildren() []Executor
- func (e *BaseExecutorV2) BuildNewBaseExecutorV2(stmtRuntimeStatsColl *execdetails.RuntimeStatsColl, schema *expression.Schema, ...) BaseExecutorV2
- func (e *BaseExecutorV2) Children(idx int) Executor
- func (e *BaseExecutorV2) ChildrenLen() int
- func (e *BaseExecutorV2) Close() error
- func (*BaseExecutorV2) Detach() (Executor, bool)
- func (e *BaseExecutorV2) EmptyChildren() bool
- func (e *BaseExecutorV2) GetSchema() *expression.Schema
- func (e *BaseExecutorV2) HandleSQLKillerSignal() error
- func (e *BaseExecutorV2) ID() int
- func (e *BaseExecutorV2) InitCap() int
- func (e *BaseExecutorV2) MaxChunkSize() int
- func (e *BaseExecutorV2) NewChunk() *chunk.Chunk
- func (e *BaseExecutorV2) NewChunkWithCapacity(fields []*types.FieldType, capacity int, maxCachesize int) *chunk.Chunk
- func (*BaseExecutorV2) Next(_ context.Context, _ *chunk.Chunk) error
- func (e *BaseExecutorV2) Open(ctx context.Context) error
- func (e *BaseExecutorV2) RegisterSQLAndPlanInExecForTopProfiling()
- func (e *BaseExecutorV2) RetFieldTypes() []*types.FieldType
- func (e *BaseExecutorV2) RuntimeStats() *execdetails.BasicRuntimeStats
- func (e *BaseExecutorV2) Schema() *expression.Schema
- func (e *BaseExecutorV2) SetAllChildren(children []Executor)
- func (e *BaseExecutorV2) SetChildren(idx int, ex Executor)
- func (e *BaseExecutorV2) SetInitCap(c int)
- func (e *BaseExecutorV2) SetMaxChunkSize(size int)
- type Executor
- type IndexUsageReporter
- func (e *IndexUsageReporter) ReportCopIndexUsage(tableID int64, physicalTableID int64, indexID int64, planID int)
- func (e *IndexUsageReporter) ReportCopIndexUsageForHandle(tbl table.Table, planID int)
- func (e *IndexUsageReporter) ReportCopIndexUsageForTable(tbl table.Table, indexID int64, planID int)
- func (e *IndexUsageReporter) ReportPointGetIndexUsage(tableID int64, physicalTableID int64, indexID int64, ...)
- func (e *IndexUsageReporter) ReportPointGetIndexUsageForHandle(tblInfo *model.TableInfo, physicalTableID int64, kvRequestTotal, rows int64)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewFirstChunk ¶
NewFirstChunk creates a new chunk to buffer current executor's result.
func TryNewCacheChunk ¶
TryNewCacheChunk tries to get a cached chunk
Types ¶
type AdaptiveLimitConfig ¶
type AdaptiveLimitConfig struct {
// DemandRows is the final-row demand derived from LIMIT offset plus count.
DemandRows uint64
// InitialOuterWindow is the starting outer-row admission window.
InitialOuterWindow uint64
// MaxOuterWindow is the upper bound of the outer-row admission window.
MaxOuterWindow uint64
// InitialLookupWindow is the starting lookup-handle admission window.
InitialLookupWindow uint64
// MaxLookupWindow is the upper bound of the lookup-handle admission window.
MaxLookupWindow uint64
// InitialLookupBatchSize is the starting number of handles assigned to one
// lookup task.
InitialLookupBatchSize uint64
// MaxLookupBatchSize is the upper bound on handles assigned to one lookup task.
MaxLookupBatchSize uint64
}
AdaptiveLimitConfig defines the immutable bounds of one statement-local adaptive LIMIT controller. Outer windows are measured in outer rows; lookup windows and batches are measured in index handles.
type AdaptiveLimitController ¶
type AdaptiveLimitController struct {
// contains filtered or unexported fields
}
AdaptiveLimitController bounds speculative work for an early-stop LIMIT. It is owned by one executor tree and learns only from the current execution.
The controller maintains two independent admission lifecycles:
outer rows: ReserveOuter -> CommitOuter -> ObserveJoinProgress lookup handles: ReserveLookup -> lookup task -> CompleteLookup / AbortLookup
Both lifecycles are active for an IndexJoin: lookup admission bounds the index handles used to produce outer rows, while outer admission bounds the rows consumed by the join to produce final rows. A direct IndexLookUp uses only the lookup lifecycle.
Outer admission is measured in IndexJoin outer rows. Lookup admission is measured in index handles. The accounting must remain separate because a table-side filter can make many handles produce few or no rows. Every reservation must eventually be committed, completed, aborted, or cleared by Stop. All mutable state below is protected by mu.
func NewAdaptiveLimitController ¶
func NewAdaptiveLimitController(config AdaptiveLimitConfig) *AdaptiveLimitController
NewAdaptiveLimitController creates a statement-local admission controller.
func NewAdaptiveLimitLookupController ¶
func NewAdaptiveLimitLookupController(config AdaptiveLimitConfig) *AdaptiveLimitController
NewAdaptiveLimitLookupController creates a controller for a direct ordered IndexLookUp under LIMIT. Direct lookup has no Join outer stage, so only its lookup handle budget is initialized.
func (*AdaptiveLimitController) AbortLookup ¶
func (c *AdaptiveLimitController) AbortLookup(handles int)
AbortLookup releases lookup admission without using the task as a yield sample. It is used for extraction errors, cancellation, and undispatched work.
func (*AdaptiveLimitController) CommitOuter ¶
func (c *AdaptiveLimitController) CommitOuter(reserved, fetched int)
CommitOuter converts an outer reservation into rows actually fetched.
func (*AdaptiveLimitController) CompleteLookup ¶
func (c *AdaptiveLimitController) CompleteLookup(reserved, handles, rows int)
CompleteLookup releases a fully consumed lookup task and learns its handle-to-row yield. reserved is admission accounting; handles is the task's actual input. Callers must report tasks in result-consumption order.
func (*AdaptiveLimitController) ObserveJoinProgress ¶
func (c *AdaptiveLimitController) ObserveJoinProgress(consumedRows, outputRows int)
ObserveJoinProgress updates input consumption and output production under one lock. Output produced before an outer row is fully consumed is retained until it can be paired with completed outer-row input.
func (*AdaptiveLimitController) ReserveLookup ¶
func (c *AdaptiveLimitController) ReserveLookup(ctx context.Context, maxHandles int) (int, bool, error)
ReserveLookup bounds handles admitted to the double-read table lookup stage. The bool is false after LIMIT completion; context cancellation is returned as an error.
func (*AdaptiveLimitController) ReserveOuter ¶
ReserveOuter waits until up to maxRows can be admitted to the join outer pipeline. The bool is false after LIMIT completion; context cancellation is returned as an error.
func (*AdaptiveLimitController) Reset ¶
func (c *AdaptiveLimitController) Reset()
Reset prepares the controller for another Open/Next/Close lifecycle. Callers must ensure all producers from the previous lifecycle have exited.
func (*AdaptiveLimitController) Snapshot ¶
func (c *AdaptiveLimitController) Snapshot() AdaptiveLimitSnapshot
Snapshot returns the current controller counters for tests and diagnostics.
func (*AdaptiveLimitController) Stop ¶
func (c *AdaptiveLimitController) Stop()
Stop prevents future admission and wakes all blocked producers.
func (*AdaptiveLimitController) SuggestedBatchSize ¶
func (c *AdaptiveLimitController) SuggestedBatchSize(ceiling int) int
SuggestedBatchSize returns the current execution batch bounded by the caller's configured batch ceiling.
type AdaptiveLimitSnapshot ¶
type AdaptiveLimitSnapshot struct {
// DemandRows is the final-row demand derived from LIMIT offset plus count.
DemandRows uint64
// OutputRows is the cumulative number of final rows observed by the controller.
OutputRows uint64
// OuterFetched is the cumulative number of committed IndexJoin outer rows.
OuterFetched uint64
// OuterConsumed is the cumulative number of outer rows fully consumed by the join.
OuterConsumed uint64
// OuterReserved is the number of admitted outer rows not yet committed or aborted.
OuterReserved uint64
// OuterWindow is the current logical outer-row admission limit.
OuterWindow uint64
// OuterOutstandingAtStop captures fetched-but-unconsumed and reserved outer
// rows when the controller stops.
OuterOutstandingAtStop uint64
// LookupReserved is the number of admitted handles not yet completed or aborted.
LookupReserved uint64
// LookupHandles is the cumulative number of handles in fully consumed lookup tasks.
LookupHandles uint64
// LookupRows is the cumulative number of table rows returned by those lookup tasks.
LookupRows uint64
// LookupWindow is the current logical lookup-handle admission limit.
LookupWindow uint64
// LookupBatchSize is the current execution-task size in index handles.
LookupBatchSize uint64
// LookupPhysicalWindow is LookupWindow rounded to executable whole batches
// without exceeding the configured maximum window.
LookupPhysicalWindow uint64
// LookupOutstandingAtStop captures reserved lookup handles when the controller stops.
LookupOutstandingAtStop uint64
// OuterAdmissionBlocked is the wall-clock time with at least one blocked
// outer reserver.
OuterAdmissionBlocked time.Duration
// LookupAdmissionBlocked is the wall-clock time with at least one blocked
// lookup reserver.
LookupAdmissionBlocked time.Duration
// Stopped reports whether the controller rejects future admission.
Stopped bool
}
AdaptiveLimitSnapshot is a point-in-time view of an AdaptiveLimitController. Outer fields are measured in outer rows. Lookup reservation, handle, window, and batch fields are measured in handles; LookupRows is measured in table rows. DemandRows and OutputRows are measured in final output rows. For an IndexJoin, output rows are observed by the join; for a direct IndexLookUp, they are observed when a lookup task is fully consumed. AdmissionBlocked fields are wall-clock durations with overlapping waits in the same stage counted once.
type BaseExecutor ¶
type BaseExecutor struct {
BaseExecutorV2
// contains filtered or unexported fields
}
BaseExecutor holds common information for executors.
func NewBaseExecutor ¶
func NewBaseExecutor(ctx sessionctx.Context, schema *expression.Schema, id int, children ...Executor) BaseExecutor
NewBaseExecutor creates a new BaseExecutor instance.
func (*BaseExecutor) AllChildren ¶
func (e *BaseExecutor) AllChildren() []Executor
AllChildren returns all children.
func (*BaseExecutor) ChildrenLen ¶
func (e *BaseExecutor) ChildrenLen() int
ChildrenLen returns the length of children.
func (*BaseExecutor) Ctx ¶
func (e *BaseExecutor) Ctx() sessionctx.Context
Ctx return ```sessionctx.Context``` of Executor
func (*BaseExecutor) EmptyChildren ¶
func (e *BaseExecutor) EmptyChildren() bool
EmptyChildren judges whether the children is empty.
func (*BaseExecutor) GetSchema ¶
func (e *BaseExecutor) GetSchema() *expression.Schema
GetSchema gets the schema.
func (*BaseExecutor) GetSysSession ¶
func (e *BaseExecutor) GetSysSession() (sessionctx.Context, error)
GetSysSession gets a system session context from executor.
func (*BaseExecutor) HandleSQLKillerSignal ¶
func (e *BaseExecutor) HandleSQLKillerSignal() error
func (*BaseExecutor) InitCap ¶
func (e *BaseExecutor) InitCap() int
InitCap returns the initial capacity for chunk
func (*BaseExecutor) MaxChunkSize ¶
func (e *BaseExecutor) MaxChunkSize() int
MaxChunkSize returns the max chunk size.
func (*BaseExecutor) NewChunk ¶
NewChunk creates a new chunk according to the executor configuration
func (*BaseExecutor) NewChunkWithCapacity ¶
func (e *BaseExecutor) NewChunkWithCapacity(fields []*types.FieldType, capacity int, maxCachesize int) *chunk.Chunk
NewChunkWithCapacity allows the caller to allocate the chunk with any types, capacity and max size in the pool
func (*BaseExecutor) RegisterSQLAndPlanInExecForTopProfiling ¶
func (e *BaseExecutor) RegisterSQLAndPlanInExecForTopProfiling()
RegisterSQLAndPlanInExecForTopProfiling registers the current SQL and Plan on top profiling.
func (*BaseExecutor) ReleaseSysSession ¶
func (e *BaseExecutor) ReleaseSysSession(ctx context.Context, sctx sessionctx.Context)
ReleaseSysSession releases a system session context to executor.
func (*BaseExecutor) RetFieldTypes ¶
NewChunkWithCapacity allows the caller to allocate the chunk with any types, capacity and max size in the pool
func (*BaseExecutor) RuntimeStats ¶
func (e *BaseExecutor) RuntimeStats() *execdetails.BasicRuntimeStats
RuntimeStats returns the runtime stats of an executor.
func (*BaseExecutor) Schema ¶
func (e *BaseExecutor) Schema() *expression.Schema
Schema returns the current BaseExecutor's schema. If it is nil, then create and return a new one.
func (*BaseExecutor) SetAllChildren ¶
func (e *BaseExecutor) SetAllChildren(children []Executor)
SetAllChildren sets the children for an executor.
func (*BaseExecutor) SetChildren ¶
SetChildren sets a child for an executor.
func (*BaseExecutor) SetInitCap ¶
func (e *BaseExecutor) SetInitCap(c int)
SetInitCap sets the initial capacity for chunk
func (*BaseExecutor) SetMaxChunkSize ¶
func (e *BaseExecutor) SetMaxChunkSize(size int)
SetMaxChunkSize sets the max chunk size.
func (*BaseExecutor) UpdateDeltaForTableID ¶
func (e *BaseExecutor) UpdateDeltaForTableID(id int64)
UpdateDeltaForTableID updates the delta info for the table with tableID.
type BaseExecutorV2 ¶
type BaseExecutorV2 struct {
// contains filtered or unexported fields
}
BaseExecutorV2 is a simplified version of `BaseExecutor`, which doesn't contain a full session context
func NewBaseExecutorV2 ¶
func NewBaseExecutorV2(vars *variable.SessionVars, schema *expression.Schema, id int, children ...Executor) BaseExecutorV2
NewBaseExecutorV2 creates a new BaseExecutorV2 instance.
func (*BaseExecutorV2) AllChildren ¶
func (e *BaseExecutorV2) AllChildren() []Executor
AllChildren returns all children.
func (*BaseExecutorV2) BuildNewBaseExecutorV2 ¶
func (e *BaseExecutorV2) BuildNewBaseExecutorV2(stmtRuntimeStatsColl *execdetails.RuntimeStatsColl, schema *expression.Schema, id int, children ...Executor) BaseExecutorV2
BuildNewBaseExecutorV2 builds a new `BaseExecutorV2` based on the configuration of the current base executor. It's used to build a new sub-executor from an existing executor. For example, the `IndexLookUpExecutor` will use this function to build `TableReaderExecutor`
func (*BaseExecutorV2) ChildrenLen ¶
func (e *BaseExecutorV2) ChildrenLen() int
ChildrenLen returns the length of children.
func (*BaseExecutorV2) Close ¶
func (e *BaseExecutorV2) Close() error
Close closes all executors and release all resources.
func (*BaseExecutorV2) Detach ¶
func (*BaseExecutorV2) Detach() (Executor, bool)
Detach detaches the current executor from the session context.
func (*BaseExecutorV2) EmptyChildren ¶
func (e *BaseExecutorV2) EmptyChildren() bool
EmptyChildren judges whether the children is empty.
func (*BaseExecutorV2) GetSchema ¶
func (e *BaseExecutorV2) GetSchema() *expression.Schema
GetSchema gets the schema.
func (*BaseExecutorV2) HandleSQLKillerSignal ¶
func (e *BaseExecutorV2) HandleSQLKillerSignal() error
func (*BaseExecutorV2) InitCap ¶
func (e *BaseExecutorV2) InitCap() int
InitCap returns the initial capacity for chunk
func (*BaseExecutorV2) MaxChunkSize ¶
func (e *BaseExecutorV2) MaxChunkSize() int
MaxChunkSize returns the max chunk size.
func (*BaseExecutorV2) NewChunk ¶
NewChunk creates a new chunk according to the executor configuration
func (*BaseExecutorV2) NewChunkWithCapacity ¶
func (e *BaseExecutorV2) NewChunkWithCapacity(fields []*types.FieldType, capacity int, maxCachesize int) *chunk.Chunk
NewChunkWithCapacity allows the caller to allocate the chunk with any types, capacity and max size in the pool
func (*BaseExecutorV2) Open ¶
func (e *BaseExecutorV2) Open(ctx context.Context) error
Open initializes children recursively and "childrenResults" according to children's schemas.
func (*BaseExecutorV2) RegisterSQLAndPlanInExecForTopProfiling ¶
func (e *BaseExecutorV2) RegisterSQLAndPlanInExecForTopProfiling()
RegisterSQLAndPlanInExecForTopProfiling registers the current SQL and Plan on top profiling.
func (*BaseExecutorV2) RetFieldTypes ¶
NewChunkWithCapacity allows the caller to allocate the chunk with any types, capacity and max size in the pool
func (*BaseExecutorV2) RuntimeStats ¶
func (e *BaseExecutorV2) RuntimeStats() *execdetails.BasicRuntimeStats
RuntimeStats returns the runtime stats of an executor.
func (*BaseExecutorV2) Schema ¶
func (e *BaseExecutorV2) Schema() *expression.Schema
Schema returns the current BaseExecutor's schema. If it is nil, then create and return a new one.
func (*BaseExecutorV2) SetAllChildren ¶
func (e *BaseExecutorV2) SetAllChildren(children []Executor)
SetAllChildren sets the children for an executor.
func (*BaseExecutorV2) SetChildren ¶
SetChildren sets a child for an executor.
func (*BaseExecutorV2) SetInitCap ¶
func (e *BaseExecutorV2) SetInitCap(c int)
SetInitCap sets the initial capacity for chunk
func (*BaseExecutorV2) SetMaxChunkSize ¶
func (e *BaseExecutorV2) SetMaxChunkSize(size int)
SetMaxChunkSize sets the max chunk size.
type Executor ¶
type Executor interface {
NewChunk() *chunk.Chunk
NewChunkWithCapacity(fields []*types.FieldType, capacity int, maxCachesize int) *chunk.Chunk
RuntimeStats() *execdetails.BasicRuntimeStats
HandleSQLKillerSignal() error
RegisterSQLAndPlanInExecForTopProfiling()
AllChildren() []Executor
SetAllChildren([]Executor)
Open(context.Context) error
Next(ctx context.Context, req *chunk.Chunk) error
// `Close()` may be called at any time after `Open()` and it may be called with `Next()` at the same time
Close() error
Schema() *expression.Schema
RetFieldTypes() []*types.FieldType
InitCap() int
MaxChunkSize() int
// Detach detaches the current executor from the session context without considering its children.
//
// It has to make sure, no matter whether it returns true or false, both the original executor and the returning executor
// should be able to be used correctly.
Detach() (Executor, bool)
}
Executor is the physical implementation of an algebra operator.
In TiDB, all algebra operators are implemented as iterators, i.e., they support a simple Open-Next-Close protocol. See this paper for more details:
"Volcano-An Extensible and Parallel Query Evaluation System"
Different from Volcano's execution model, a "Next" function call in TiDB will return a batch of rows, other than a single row in Volcano. NOTE: Executors must call "chk.Reset()" before appending their results to it.
type IndexUsageReporter ¶
type IndexUsageReporter struct {
// contains filtered or unexported fields
}
IndexUsageReporter is a toolkit to report index usage
func NewIndexUsageReporter ¶
func NewIndexUsageReporter(reporter *indexusage.StmtIndexUsageCollector, runtimeStatsColl *execdetails.RuntimeStatsColl, statsMap *stmtctx.UsedStatsInfo) *IndexUsageReporter
NewIndexUsageReporter creates an index usage reporter util
func (*IndexUsageReporter) ReportCopIndexUsage ¶
func (e *IndexUsageReporter) ReportCopIndexUsage(tableID int64, physicalTableID int64, indexID int64, planID int)
ReportCopIndexUsage reports the index usage to the inside collector. The index usage will be recorded in the `tableID+indexID`, but the percentage is calculated using the size of the table specified by `physicalTableID`.
func (*IndexUsageReporter) ReportCopIndexUsageForHandle ¶
func (e *IndexUsageReporter) ReportCopIndexUsageForHandle(tbl table.Table, planID int)
ReportCopIndexUsageForHandle wraps around `ReportCopIndexUsageForTable` to get the `indexID` automatically from the `table.Table` if the table has a clustered index or clustered integer primary key. If the table has a non-clustered PK or no PK, this function simply returns without reporting index usage.
func (*IndexUsageReporter) ReportCopIndexUsageForTable ¶
func (e *IndexUsageReporter) ReportCopIndexUsageForTable(tbl table.Table, indexID int64, planID int)
ReportCopIndexUsageForTable wraps around `ReportCopIndexUsage` to get `tableID` and `physicalTableID` from the `table.Table`. If it's expected to calculate the percentage according to the size of partition, the `tbl` argument should be a `table.PhysicalTable`, or the percentage will be calculated using the size of whole table.
func (*IndexUsageReporter) ReportPointGetIndexUsage ¶
func (e *IndexUsageReporter) ReportPointGetIndexUsage(tableID int64, physicalTableID int64, indexID int64, kvRequestTotal, rows int64)
ReportPointGetIndexUsage reports the index usage of a point get or batch point get
func (*IndexUsageReporter) ReportPointGetIndexUsageForHandle ¶
func (e *IndexUsageReporter) ReportPointGetIndexUsageForHandle(tblInfo *model.TableInfo, physicalTableID int64, kvRequestTotal, rows int64)
ReportPointGetIndexUsageForHandle wraps around `ReportPointGetIndexUsage` to get the `indexID` automatically from the `table.Table` if the table has a clustered index or integer primary key.