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 写操作次数 |
---|---|---|---|---|
100 | 6.99 | 14305.95 | 133.75 | 747.65 |
1000 | 60.90 | 16419.55 | 1030.82 | 970.10 |
5000 | 281.99 | 17730.98 | 6378.48 | 783.89 |
10000 | 788.88 | 12676.23 | 11064.64 | 903.78 |
20000 | 1460.66 | 13692.47 | 20683.92 | 966.93 |
更新操作性能对比
在需要频繁更新数据的场景中,我们比较了MySQL和Redis的更新操作性能。以下是测试结果:
操作次数 | Redis 更新操作总耗时 (ms) | 每秒 Redis 更新操作次数 | MySQL 更新操作总耗时 (ms) | 每秒 MySQL 更新操作次数 |
---|---|---|---|---|
100 | 321.22 | 311.31 | 151.35 | 660.73 |
1000 | 360.26 | 2775.80 | 1058.13 | 945.07 |
5000 | 587.03 | 8517.50 | 6476.15 | 772.06 |
10000 | 972.09 | 10287.10 | 10355.73 | 965.65 |
20000 | 1830.00 | 10928.93 | 21932.29 | 911.90 |
读操作性能对比
对于需要高效读取数据的应用,我们比较了MySQL和Redis在不同操作次数下的读操作性能。以下是测试结果:
操作次数 | Redis 读操作总耗时 (ms) | 每秒 Redis 读操作次数 | MySQL 读操作总耗时 (ms) | 每秒 MySQL 读操作次数 |
---|---|---|---|---|
100 | 312.76 | 319.73 | 52.16 | 1917.11 |
1000 | 373.24 | 2679.23 | 250.83 | 3986.83 |
5000 | 586.68 | 8522.55 | 1751.84 | 2854.14 |
10000 | 840.40 | 11899.11 | 2614.62 | 3824.65 |
20000 | 2025.08 | 9876.14 | 4992.74 | 4005.81 |
删除操作性能对比
最后,我们比较了MySQL和Redis在删除操作场景中的性能表现。以下是测试结果:
操作次数 | Redis 删除操作总耗时 (ms) | 每秒 Redis 删除操作次数 | MySQL 删除操作总耗时 (ms) | 每秒 MySQL 删除操作次数 |
---|---|---|---|---|
100 | 309.40 | 323.20 | 162.35 | 615.96 |
1000 | 366.92 | 2725.39 | 1006.20 | 993.84 |
5000 | 571.77 | 8744.78 | 5868.90 | 851.95 |
10000 | 877.23 | 11399.48 | 10908.71 | 916.70 |
20000 | 1670.48 | 11972.59 | 21065.37 | 949.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
}