code: func (e *IndexLookUpExecutor) startTableWorker(ctx context.Context, workCh <-chan *lookupTableTask) {
  	lookupConcurrencyLimit := e.ctx.GetSessionVars().IndexLookupConcurrency
  	e.tblWorkerWg.Add(lookupConcurrencyLimit)
  	for i := 0; i < lookupConcurrencyLimit; i++ {
  		worker := &tableWorker{
  			idxLookup:      e,
  			workCh:         workCh,
  			finished:       e.finished,
  			buildTblReader: e.buildTableReader,
  			keepOrder:      e.keepOrder,
  			handleIdx:      e.handleIdx,
  			isCheckOp:      e.isCheckOp,
  			memTracker:     memory.NewTracker(tableWorkerLabel, -1),
  		}
  		worker.memTracker.AttachTo(e.memTracker)
  		ctx1, cancel := context.WithCancel(ctx)
  		go func() {
  			worker.pickAndExecTask(ctx1)
  			cancel()
  			e.tblWorkerWg.Done()
  		}()
  	}
  }
docs: // startTableWorker launchs some background goroutines which pick tasks from workCh and execute the task.