AI 中文社区(简称 AI 中文社),是国内学习交流AI人工智能技术的中文社区网站,这里可获取及贡献任何AI人工智能技术,我们追求自由、简洁、纯粹、分享的多元化人工智能社区。

AI 中文社网站切换到 GORM 之前,测试原生 SQL、SQLX、GORM 性能

随笔 · 杰作 2023年04月29日发布 · 浏览498次 · 点赞1次 · 收藏1次

Go 领域里,原生 SQL、SQLX、GORM 性能相差多少呢?几天打算测试比较它们的性能。AI 中文社网站数据库操作类库是我封装了 jmoiron/sqlx 的一个类,在开发过程中,发现这个库比原生的 database/sql 操作方便一些,起码填充数据结构的时候,省了很多代码,介于原生与 ORM 之间,但是远远达不到 ORM 这么方便,很多动态参数,掺杂了数据库字段在里面,如果日后修改数据库后,很容易出错,心里痒痒的,想用回 ORM ,这样代码优雅些,让代码健壮一些。


所以拿 database/sql,jmoiron/sqlx,gorm.io/gorm 三个库进行了性能测试,看看相差多少,从性能和健壮性上权衡,再决定下一步怎么选择,测试环境 MacBook Pro (Retina, 13-inch, Early 2015) ,2.7 GHz Intel Core i5 ,固态磁盘 256G, 内存 8 GB 1867 MHz DDR3,,数据库 PostgreSQL15。


测试结果如下:


看到最终的测试结果,发现 grom 的性能相对于原生的 database/sql 低了 6% - 50% 左右,特别并发量增加上去后越明显,而 jmoiron/sqlx 性能很接近原生的 database/sql ,并发量上次之后 3%-18% 的损耗,中低并发量的时候和原生性能不分仲伯,日常情况下,估计整体表现非常优异。这次测试,让我犹豫要不要切换 grom 了,反复测试了多次,测试结果稳定,代码发出来,大家看看有没有不公平的地方,我再检验。

package main

import (
	"database/sql"
	"fmt"
	"testing"

	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

// go test -bench=. -benchmem -run=none
var (
	dsn = "postgres://postgres:123456@localhost:5432/demo?sslmode=disable"
)

type Person struct {
	Id        int    `db:"id"`
	FirstName string `db:"first_name"`
	LastName  string `db:"last_name"`
	Email     string `db:"email"`
}

func (p Person) TableName() string {
	return "person"
}

func Benchmark(b *testing.B) {
	limits := []int{
		10,
		100,
		1000,
		10000,
	}

	// 原生 database/sql 连接池
	sqlDB, _ := sql.Open("postgres", dsn)
	sqlDB.SetMaxOpenConns(500)
	sqlDB.SetMaxIdleConns(100)

	// jmoiron/sqlx 连接池
	sqlxDB, _ := sqlx.Connect("postgres", dsn)
	sqlxDB.SetMaxOpenConns(500)
	sqlxDB.SetMaxIdleConns(100)

	// gorm.io/gorm
	gormDB, _ := gorm.Open(postgres.Open(dsn), &gorm.Config{
		SkipDefaultTransaction: true,
		PrepareStmt:            true,
		DisableAutomaticPing:   true,
	})
	db, _ := gormDB.DB()
	db.SetMaxOpenConns(500)
	db.SetMaxIdleConns(100)

	for _, lim := range limits {
		// Benchmark database/sql
		b.Run(fmt.Sprintf("database/sql limit:%d", lim), func(b *testing.B) {
			var res []Person
			stmt, _ := sqlDB.Prepare("SELECT id,first_name,last_name,email FROM person LIMIT $1")
			for i := 0; i < b.N; i++ {
				rows, err := stmt.Query(lim)
				if err != nil {
					b.Fatal(err)
				}
				defer rows.Close()

				for rows.Next() {
					p := Person{}
					rows.Scan(&p.Id, &p.FirstName, &p.LastName, &p.Email)
					res = append(res, p)
				}
			}
		})

		// Benchmark jmoiron/sqlx
		b.Run(fmt.Sprintf("jmoiron/sqlx limit:%d", lim), func(b *testing.B) {
			stmt, _ := sqlxDB.Preparex("SELECT id,first_name,last_name,email FROM person LIMIT $1")
			for i := 0; i < b.N; i++ {
				var res []Person
				err := stmt.Select(&res, lim)
				if err != nil {
					b.Fatal(err)
				}
			}
		})

		// Benchmark gorm.io/gorm
		b.Run(fmt.Sprintf("gorm.io/gorm limit:%d", lim), func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				var res []Person
				err := gormDB.Limit(lim).Find(&res).Error
				if err != nil {
					b.Fatal(err)
				}
			}
		})

		fmt.Println("#######################################")
	}
}
AI 中文社网站切换到 GORM 之前,测试原生 SQL、SQLX、GORM 性能 - 随笔 - 话题 - AI 中文社区
点赞(1) 收藏(1)
0条评论
现在评论,你将成小区里最靓的仔^_^
评论

游客
登录后再评论
  • 一字一句需斟酌,一言一语显风范。
  • 评论消耗5积分,点赞、收藏消耗3积分。