Backend Development 7 min read

Performance Testing of MySQL Using GORM and the FunTester Framework in Go

This article demonstrates how to use the Go-based FunTester framework to conduct performance tests—select, insert, update, and delete—on MySQL through GORM, providing code examples and explaining the setup of the testing harness.

FunTester
FunTester
FunTester
Performance Testing of MySQL Using GORM and the FunTester Framework in Go

In a previous article titled Go Language GORM Framework MySQL Practice , basic operations of GORM with MySQL were covered. This article shares a simple practice for directly performance‑testing MySQL using the GORM framework.

Framework Support

The author uses a lightweight Go testing framework called FunTester . The framework leverages Go's closures and function‑parameter features, treating a func() as the performance‑test subject and repeatedly executing it. An alternative approach is to run a multithreaded task similar to the Java abstract class com.funtester.base.constaint.ThreadBase , allowing more test scenarios.

// ExecuteRoutineTimes
// @Description: FunTester performance test execution framework
// @param fun function to execute
// @param times number of executions per thread
// @param thread number of concurrent threads
func ExecuteRoutineTimes(fun func(), t int, r int) {
    c := make(chan int) // confirm all threads finish
    key := false        // control all threads to finish together
    start := futil.Milli()
    for i := 0; i < r; i++ {
        go func() {
            sum := 0
            for i := 0; i < t; i++ {
                if key {
                    break
                }
                fun()
                sum++
            }
            key = true
            c <- sum
        }()
    }
    total := 0
    for i := 0; i < r; i++ {
        num := <-c
        total += num
    }
    end := futil.Milli()
    diff := end - start
    //total := thread * times
    log.Printf("Total time: %f", float64(diff)/1000)
    log.Printf("Total requests: %d", total)
    log.Printf("QPS: %f", float64(total)/float64(diff)*1000.0)
}

select

The following demonstrates a performance test for a SELECT operation using random ID queries.

func TestSelectP(t *testing.T) {
    execute.ExecuteRoutineTimes(func() {
        var f Funtester
        drive.Where("id = ?", futil.RangInt(35, 20000)).First(&f)
    }, 1000, 100)
}

delete

This test deletes records using incrementally increasing IDs starting from 35.

func TestDeleteP(t *testing.T) {
    var index int32 = 35
    execute.ExecuteRoutineTimes(func() {
        id := atomic.AddInt32(&index, 1)
        drive.Where("id = ?", id).Delete(&Funtester{})
    }, 1000, 100)
}

update

The update test reuses the SELECT scenario, picking a random ID and updating the name field with a random 10‑character string.

func TestUpdateP(t *testing.T) {
    execute.ExecuteRoutineTimes(func() {
        drive.Where("id = ?", futil.RangInt(35, 20000)).Update("name", futil.RandomStr(10))
    }, 1000, 100)
}

insert

The insert test creates records with randomly generated fields using the FunTester struct.

func TestInsertP(t *testing.T) {
    execute.ExecuteRoutineTimes(func() {
        drive.Create(&Funtester{Name: futil.RandomStr(10), Age: futil.RandomInt(100)})
    }, 1000, 100)
}

FunTester Constructor

type Funtester struct {
    gorm.Model
    Name string
    Age  int
}

All performance tests use the basic GORM API; connection‑pool management is delegated entirely to GORM. This is comparable to configuring an HTTP client’s connection pool, showing how powerful frameworks can be simple to use.

For fundamental GORM usage, refer to the previous article Go Language GORM Framework MySQL Practice .

Have Fun ~ Tester !

FunTester 2021 Summary

FunTester Original Works

Performance Test Series – FunTester Original

backendDatabaseGoperformance testingMySQLGormfun-tester
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.