github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/stats/query.go (about)

     1  package stats
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_TableStats"
     7  )
     8  
     9  type (
    10  	// QueryStats holds query execution statistics.
    11  	QueryStats interface {
    12  		ProcessCPUTime() time.Duration
    13  		Compilation() (c *CompilationStats)
    14  		QueryPlan() string
    15  		QueryAST() string
    16  		TotalCPUTime() time.Duration
    17  		TotalDuration() time.Duration
    18  
    19  		// NextPhase returns next execution phase within query.
    20  		// If ok flag is false, then there are no more phases and p is invalid.
    21  		NextPhase() (p QueryPhase, ok bool)
    22  	}
    23  	// QueryPhase holds query execution phase statistics.
    24  	QueryPhase interface {
    25  		// NextTableAccess returns next accessed table within query execution phase.
    26  		// If ok flag is false, then there are no more accessed tables and t is invalid.
    27  		NextTableAccess() (t *TableAccess, ok bool)
    28  		Duration() time.Duration
    29  		CPUTime() time.Duration
    30  		AffectedShards() uint64
    31  		IsLiteralPhase() bool
    32  	}
    33  	OperationStats struct {
    34  		Rows  uint64
    35  		Bytes uint64
    36  	}
    37  	Phase struct {
    38  		Duration       time.Duration
    39  		TableAccess    []TableAccess
    40  		CPUTime        time.Duration
    41  		AffectedShards uint64
    42  		LiteralPhase   bool
    43  	}
    44  	// TableAccess contains query execution phase's table access statistics.
    45  	TableAccess struct {
    46  		Name            string
    47  		Reads           OperationStats
    48  		Updates         OperationStats
    49  		Deletes         OperationStats
    50  		PartitionsCount uint64
    51  	}
    52  	// CompilationStats holds query compilation statistics.
    53  	CompilationStats struct {
    54  		FromCache bool
    55  		Duration  time.Duration
    56  		CPUTime   time.Duration
    57  	}
    58  	// queryStats holds query execution statistics.
    59  	queryStats struct {
    60  		pb  *Ydb_TableStats.QueryStats
    61  		pos int
    62  	}
    63  	// queryPhase holds query execution phase statistics.
    64  	queryPhase struct {
    65  		pb  *Ydb_TableStats.QueryPhaseStats
    66  		pos int
    67  	}
    68  )
    69  
    70  func fromUs(us uint64) time.Duration {
    71  	return time.Duration(us) * time.Microsecond
    72  }
    73  
    74  func fromCompilationStats(pb *Ydb_TableStats.CompilationStats) *CompilationStats {
    75  	return &CompilationStats{
    76  		FromCache: pb.GetFromCache(),
    77  		Duration:  fromUs(pb.GetDurationUs()),
    78  		CPUTime:   fromUs(pb.GetCpuTimeUs()),
    79  	}
    80  }
    81  
    82  func fromOperationStats(pb *Ydb_TableStats.OperationStats) OperationStats {
    83  	return OperationStats{
    84  		Rows:  pb.GetRows(),
    85  		Bytes: pb.GetBytes(),
    86  	}
    87  }
    88  
    89  func (s *queryStats) ProcessCPUTime() time.Duration {
    90  	return fromUs(s.pb.GetProcessCpuTimeUs())
    91  }
    92  
    93  func (s *queryStats) Compilation() (c *CompilationStats) {
    94  	return fromCompilationStats(s.pb.GetCompilation())
    95  }
    96  
    97  func (s *queryStats) QueryPlan() string {
    98  	return s.pb.GetQueryPlan()
    99  }
   100  
   101  func (s *queryStats) QueryAST() string {
   102  	return s.pb.GetQueryAst()
   103  }
   104  
   105  func (s *queryStats) TotalCPUTime() time.Duration {
   106  	return fromUs(s.pb.GetTotalCpuTimeUs())
   107  }
   108  
   109  func (s *queryStats) TotalDuration() time.Duration {
   110  	return fromUs(s.pb.GetTotalDurationUs())
   111  }
   112  
   113  // NextPhase returns next execution phase within query.
   114  // If ok flag is false, then there are no more phases and p is invalid.
   115  func (s *queryStats) NextPhase() (p QueryPhase, ok bool) {
   116  	if s.pos >= len(s.pb.GetQueryPhases()) {
   117  		return
   118  	}
   119  	pb := s.pb.GetQueryPhases()[s.pos]
   120  	if pb == nil {
   121  		return
   122  	}
   123  	s.pos++
   124  
   125  	return &queryPhase{
   126  		pb: pb,
   127  	}, true
   128  }
   129  
   130  // NextTableAccess returns next accessed table within query execution phase.
   131  //
   132  // If ok flag is false, then there are no more accessed tables and t is
   133  // invalid.
   134  func (queryPhase *queryPhase) NextTableAccess() (t *TableAccess, ok bool) {
   135  	if queryPhase.pos >= len(queryPhase.pb.GetTableAccess()) {
   136  		return
   137  	}
   138  	pb := queryPhase.pb.GetTableAccess()[queryPhase.pos]
   139  	queryPhase.pos++
   140  
   141  	return &TableAccess{
   142  		Name:            pb.GetName(),
   143  		Reads:           fromOperationStats(pb.GetReads()),
   144  		Updates:         fromOperationStats(pb.GetUpdates()),
   145  		Deletes:         fromOperationStats(pb.GetDeletes()),
   146  		PartitionsCount: pb.GetPartitionsCount(),
   147  	}, true
   148  }
   149  
   150  func (queryPhase *queryPhase) Duration() time.Duration {
   151  	return fromUs(queryPhase.pb.GetDurationUs())
   152  }
   153  
   154  func (queryPhase *queryPhase) CPUTime() time.Duration {
   155  	return fromUs(queryPhase.pb.GetCpuTimeUs())
   156  }
   157  
   158  func (queryPhase *queryPhase) AffectedShards() uint64 {
   159  	return queryPhase.pb.GetAffectedShards()
   160  }
   161  
   162  func (queryPhase *queryPhase) IsLiteralPhase() bool {
   163  	return queryPhase.pb.GetLiteralPhase()
   164  }
   165  
   166  func FromQueryStats(pb *Ydb_TableStats.QueryStats) QueryStats {
   167  	if pb == nil {
   168  		return nil
   169  	}
   170  
   171  	return &queryStats{
   172  		pb: pb,
   173  	}
   174  }