MySQL vs Redis 性能实测记录 | 青训营

391 阅读5分钟

MySQL vs Redis 性能实测记录


引言

在当今快节奏的应用环境中,数据库性能对于应用程序的成功至关重要。MySQL和Redis作为两种广泛使用的数据库系统,在性能方面有着不同的特点和优势。本文将对MySQL和Redis进行性能对比,从写操作、读操作、更新和删除操作等不同方面,分析它们在不同操作次数下的性能表现。

测试环境设置

  • CPU:AMD Ryzen 5 3500U 4核8线程
  • 内存:16GB
  • 数据库版本:MySQL 8.0,Redis 7.0.11
  • 测试工具:Go语言性能程序

写操作性能对比

写操作对于许多应用来说是至关重要的,我们首先比较了MySQL和Redis在不同操作次数下的写操作性能。以下是测试结果:

操作次数Redis 写操作总耗时 (ms)每秒 Redis 写操作次数MySQL 写操作总耗时 (ms)每秒 MySQL 写操作次数
1006.9914305.95133.75747.65
100060.9016419.551030.82970.10
5000281.9917730.986378.48783.89
10000788.8812676.2311064.64903.78
200001460.6613692.4720683.92966.93

更新操作性能对比

在需要频繁更新数据的场景中,我们比较了MySQL和Redis的更新操作性能。以下是测试结果:

操作次数Redis 更新操作总耗时 (ms)每秒 Redis 更新操作次数MySQL 更新操作总耗时 (ms)每秒 MySQL 更新操作次数
100321.22311.31151.35660.73
1000360.262775.801058.13945.07
5000587.038517.506476.15772.06
10000972.0910287.1010355.73965.65
200001830.0010928.9321932.29911.90

读操作性能对比

对于需要高效读取数据的应用,我们比较了MySQL和Redis在不同操作次数下的读操作性能。以下是测试结果:

操作次数Redis 读操作总耗时 (ms)每秒 Redis 读操作次数MySQL 读操作总耗时 (ms)每秒 MySQL 读操作次数
100312.76319.7352.161917.11
1000373.242679.23250.833986.83
5000586.688522.551751.842854.14
10000840.4011899.112614.623824.65
200002025.089876.144992.744005.81

删除操作性能对比

最后,我们比较了MySQL和Redis在删除操作场景中的性能表现。以下是测试结果:

操作次数Redis 删除操作总耗时 (ms)每秒 Redis 删除操作次数MySQL 删除操作总耗时 (ms)每秒 MySQL 删除操作次数
100309.40323.20162.35615.96
1000366.922725.391006.20993.84
5000571.778744.785868.90851.95
10000877.2311399.4810908.71916.70
200001670.4811972.5921065.37949.43

测试代码

 package main
 ​
 import (
     "database/sql"
     "fmt"
     "github.com/go-redis/redis/v8"
     _ "github.com/go-sql-driver/mysql"
     "golang.org/x/net/context"
     "log"
     "time"
 )
 ​
 func main() {
     // 操作次数
     operations := []int{100, 1000, 5000, 10000, 20000}
 ​
     for _, numOperations := range operations {
         fmt.Printf("操作次数:%d\n", numOperations)
         fmt.Printf("Redis:\n")
         testRedis(numOperations)
         fmt.Printf("MySQL:\n")
         testMySQL(numOperations)
     }
 ​
 }
 ​
 func testRedis(numOperations int) {
     redisWriteTest(numOperations)
     redisUpdateTest(numOperations)
     redisReadTest(numOperations)
     redisDeleteTest(numOperations)
 }
 ​
 // 测试写操作性能
 func redisWriteTest(numOperations int) float64 {
     client := redis.NewClient(&redis.Options{
         Addr:     "localhost:6379",
         Password: "",
         DB:       0,
     })
 ​
     ctx := context.Background()
     _, err := client.Ping(ctx).Result()
     if err != nil {
         log.Fatalf("连接到Redis失败: %v", err)
     }
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         err := client.Set(ctx, fmt.Sprintf("key%d", i), i, 0).Err()
         if err != nil {
             log.Fatalf("写入Redis时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("写操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒写操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 // 测试更新操作性能
 func redisUpdateTest(numOperations int) float64 {
     client := redis.NewClient(&redis.Options{
         Addr:     "localhost:6379",
         Password: "",
         DB:       0,
     })
 ​
     ctx := context.Background()
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         err := client.Set(ctx, fmt.Sprintf("key%d", i), i*2, 0).Err()
         if err != nil {
             log.Fatalf("更新Redis时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("更新操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒更新操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 // 测试读操作性能
 func redisReadTest(numOperations int) float64 {
     client := redis.NewClient(&redis.Options{
         Addr:     "localhost:6379",
         Password: "",
         DB:       0,
     })
 ​
     ctx := context.Background()
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         _, err := client.Get(ctx, fmt.Sprintf("key%d", i)).Result()
         if err != nil {
             log.Fatalf("从Redis读取时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("读操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒读操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 // 测试删除操作性能
 func redisDeleteTest(numOperations int) float64 {
     client := redis.NewClient(&redis.Options{
         Addr:     "localhost:6379",
         Password: "",
         DB:       0,
     })
 ​
     ctx := context.Background()
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         _, err := client.Del(ctx, fmt.Sprintf("key%d", i)).Result()
         if err != nil {
             log.Fatalf("从Redis删除时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("删除操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒删除操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 func testMySQL(numOperations int) {
     mysqlWriteTest(numOperations)
     mysqlUpdateTest(numOperations)
     mysqlReadTest(numOperations)
     mysqlDeleteTest(numOperations)
 }
 ​
 // 测试写操作性能
 func mysqlWriteTest(numOperations int) float64 {
     db, err := sql.Open("mysql", "root:MySQL@123@tcp(localhost:3306)/test")
     if err != nil {
         log.Fatalf("连接到MySQL失败: %v", err)
     }
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         _, err := db.Exec("INSERT INTO test_table (key_column, value_column) VALUES (?, ?)", i, i)
         if err != nil {
             log.Fatalf("写入MySQL时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("写操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒写操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 // 测试读操作性能
 func mysqlReadTest(numOperations int) float64 {
     db, err := sql.Open("mysql", "root:MySQL@123@tcp(localhost:3306)/test")
     if err != nil {
         log.Fatalf("连接到MySQL失败: %v", err)
     }
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         var value int
         err := db.QueryRow("SELECT value_column FROM test_table WHERE key_column = ?", i).Scan(&value)
         if err != nil {
             log.Fatalf("从MySQL读取时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("读操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒读操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 // 测试更新操作性能
 func mysqlUpdateTest(numOperations int) float64 {
     db, err := sql.Open("mysql", "root:MySQL@123@tcp(localhost:3306)/test")
     if err != nil {
         log.Fatalf("连接到MySQL失败: %v", err)
     }
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         _, err := db.Exec("UPDATE test_table SET value_column = ? WHERE key_column = ?", i*2, i)
         if err != nil {
             log.Fatalf("更新MySQL时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("更新操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒更新操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​
 // 测试删除操作性能
 func mysqlDeleteTest(numOperations int) float64 {
     db, err := sql.Open("mysql", "root:MySQL@123@tcp(localhost:3306)/test")
     if err != nil {
         log.Fatalf("连接到MySQL失败: %v", err)
     }
 ​
     startTime := time.Now()
 ​
     for i := 0; i < numOperations; i++ {
         _, err := db.Exec("DELETE FROM test_table WHERE key_column = ?", i)
         if err != nil {
             log.Fatalf("从MySQL删除时出错: %v", err)
         }
     }
 ​
     elapsed := time.Since(startTime)
     opsPerSec := float64(numOperations) / elapsed.Seconds()
 ​
     fmt.Printf("删除操作总耗时: %v\n", elapsed)
     fmt.Printf("每秒删除操作次数: %.2f\n", opsPerSec)
     return opsPerSec
 }
 ​