vitess.io/vitess@v0.16.2/go/mysql/query_benchmark_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mysql 18 19 import ( 20 "context" 21 "math/rand" 22 "net" 23 "strings" 24 "testing" 25 ) 26 27 // Override the default here to test with different values. 28 var testReadConnBufferSize = connBufferSize 29 30 const benchmarkQueryPrefix = "benchmark " 31 32 type mkListenerCfg func(AuthServer, Handler) ListenerConfig 33 34 func mkDefaultListenerCfg(authServer AuthServer, handler Handler) ListenerConfig { 35 return ListenerConfig{ 36 Protocol: "tcp", 37 Address: "127.0.0.1:", 38 AuthServer: authServer, 39 Handler: handler, 40 ConnReadBufferSize: testReadConnBufferSize, 41 } 42 } 43 44 func mkReadBufferPoolingCfg(authServer AuthServer, handler Handler) ListenerConfig { 45 cfg := mkDefaultListenerCfg(authServer, handler) 46 cfg.ConnBufferPooling = true 47 return cfg 48 } 49 50 func benchmarkQuery(b *testing.B, threads int, query string, mkCfg mkListenerCfg) { 51 th := &testHandler{} 52 53 authServer := NewAuthServerNone() 54 55 lCfg := mkCfg(authServer, th) 56 57 l, err := NewListenerWithConfig(lCfg) 58 if err != nil { 59 b.Fatalf("NewListener failed: %v", err) 60 } 61 defer l.Close() 62 63 go func() { 64 l.Accept() 65 }() 66 67 b.SetParallelism(threads) 68 if query != "" { 69 b.SetBytes(int64(len(query))) 70 } 71 72 host := l.Addr().(*net.TCPAddr).IP.String() 73 port := l.Addr().(*net.TCPAddr).Port 74 params := &ConnParams{ 75 Host: host, 76 Port: port, 77 Uname: "user1", 78 Pass: "password1", 79 } 80 ctx := context.Background() 81 82 b.ResetTimer() 83 84 // MaxPacketSize is too big for benchmarks, so choose something smaller 85 maxPacketSize := connBufferSize * 4 86 87 b.RunParallel(func(pb *testing.PB) { 88 conn, err := Connect(ctx, params) 89 if err != nil { 90 b.Fatal(err) 91 } 92 defer func() { 93 conn.writeComQuit() 94 conn.Close() 95 }() 96 97 for pb.Next() { 98 execQuery := query 99 if execQuery == "" { 100 // generate random query 101 n := rand.Intn(maxPacketSize-len(benchmarkQueryPrefix)) + 1 102 execQuery = benchmarkQueryPrefix + strings.Repeat("x", n) 103 104 } 105 if _, err := conn.ExecuteFetch(execQuery, 1000, true); err != nil { 106 b.Fatalf("ExecuteFetch failed: %v", err) 107 } 108 } 109 }) 110 } 111 112 // This file contains various long-running tests for mysql. 113 114 // BenchmarkParallelShortQueries creates N simultaneous connections, then 115 // executes M queries on them, then closes them. 116 // It is meant as a somewhat real load test. 117 func BenchmarkParallelShortQueries(b *testing.B) { 118 benchmarkQuery(b, 10, benchmarkQueryPrefix+"select rows", mkDefaultListenerCfg) 119 } 120 121 func BenchmarkParallelMediumQueries(b *testing.B) { 122 benchmarkQuery( 123 b, 124 10, 125 benchmarkQueryPrefix+"select"+strings.Repeat("x", connBufferSize), 126 mkDefaultListenerCfg, 127 ) 128 } 129 130 func BenchmarkParallelRandomQueries(b *testing.B) { 131 benchmarkQuery(b, 10, "", mkDefaultListenerCfg) 132 } 133 134 func BenchmarkParallelShortQueriesWithReadBufferPooling(b *testing.B) { 135 benchmarkQuery(b, 10, benchmarkQueryPrefix+"select rows", mkReadBufferPoolingCfg) 136 } 137 138 func BenchmarkParallelMediumQueriesWithReadBufferPooling(b *testing.B) { 139 benchmarkQuery( 140 b, 141 10, 142 benchmarkQueryPrefix+"select"+strings.Repeat("x", connBufferSize), 143 mkReadBufferPoolingCfg, 144 ) 145 } 146 147 func BenchmarkParallelRandomQueriesWithReadBufferPooling(b *testing.B) { 148 benchmarkQuery(b, 10, "", mkReadBufferPoolingCfg) 149 }