本文档风哥主要介绍MySQL内存表优化的实战技巧,包括MEMORY存储引擎使用、内存表设计原则、应用场景等内容,风哥教程参考MySQL官方文档,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 内存表概述
内存表是将数据存储在内存中的特殊表类型:
1. 内存表定义
内存表特点:
– 数据存储在内存中
– 访问速度极快
– 重启后数据丢失
– 表结构持久化
内存表优势:
– 极高的读写性能
– 低延迟访问
– 适合临时数据
– 适合缓存场景
内存表限制:
– 数据不持久化
– 内存容量限制
– 不支持事务
– 不支持BLOB/TEXT
2. 查看内存表支持
检查MEMORY引擎支持:
mysql> SHOW ENGINES;
输出示例:
+——————–+———+—————————————————————-+————–+——+————+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+——————–+———+—————————————————————-+————–+——+————+
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
+——————–+———+—————————————————————-+————–+——+————+
查看内存表变量:
mysql> SHOW VARIABLES LIKE ‘%max_heap_table_size%’;
输出示例:
+———————+———-+
| Variable_name | Value |
+———————+———-+
| max_heap_table_size | 16777216 |
+———————+———-+
3. 创建内存表
创建MEMORY引擎表:
mysql> CREATE TABLE session_cache (
session_id VARCHAR(64) PRIMARY KEY,
user_id INT,
login_time TIMESTAMP,
expire_time TIMESTAMP,
data JSON
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
查看表结构:
mysql> SHOW CREATE TABLE session_cache\G
输出示例:
*************************** 1. row ***************************
Table: session_cache
Create Table: CREATE TABLE `session_cache` (
`session_id` varchar(64) NOT NULL,
`user_id` int DEFAULT NULL,
`login_time` timestamp NULL DEFAULT NULL,
`expire_time` timestamp NULL DEFAULT NULL,
`data` json DEFAULT NULL,
PRIMARY KEY (`session_id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4
4. 内存表操作
插入数据:
mysql> INSERT INTO session_cache
(session_id, user_id, login_time, expire_time)
VALUES
(‘abc123’, 1, NOW(), DATE_ADD(NOW(), INTERVAL 1 HOUR));
输出示例:
Query OK, 1 row affected (0.00 sec)
查询数据:
mysql> SELECT * FROM session_cache WHERE session_id = ‘abc123’;
输出示例:
+————+———+———————+———————+——+
| session_id | user_id | login_time | expire_time | data |
+————+———+———————+———————+——+
| abc123 | 1 | 2026-04-01 10:00:00 | 2026-04-01 11:00:00 | NULL |
+————+———+———————+———————+——+
删除数据:
mysql> DELETE FROM session_cache WHERE session_id = ‘abc123’;
输出示例:
Query OK, 1 row affected (0.00 sec)
5. 内存表大小限制
查看当前内存表大小:
mysql> SELECT
TABLE_NAME,
TABLE_ROWS,
DATA_LENGTH,
INDEX_LENGTH
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
输出示例:
+—————+————+————-+————-+
| TABLE_NAME | TABLE_ROWS | DATA_LENGTH | INDEX_LENGTH|
+—————+————+————-+————-+
| session_cache| 100 | 16384 | 8192 |
+—————+————+————-+————-+
设置内存表最大大小:
mysql> SET max_heap_table_size = 256*1024*1024;
输出示例:
Query OK, 0 rows affected (0.00 sec)
1.2 MEMORY存储引擎
MEMORY存储引擎是MySQL内置的内存存储引擎:
1. 存储引擎特性
MEMORY引擎特点:
– 数据存储在内存中
– 使用哈希索引(默认)
– 支持B-tree索引
– 表级锁
与InnoDB对比:
+——————-+——————+——————+
| 特性 | MEMORY | InnoDB |
+——————-+——————+——————+
| 存储位置 | 内存 | 磁盘 |
| 持久化 | 否 | 是 |
| 事务支持 | 否 | 是 |
| 锁粒度 | 表级 | 行级 |
| 索引类型 | HASH/B-tree | B-tree |
+——————-+——————+——————+
2. 索引类型
创建HASH索引(默认):
mysql> CREATE TABLE user_cache (
id INT PRIMARY KEY,
name VARCHAR(100),
INDEX USING HASH (name)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
创建BTREE索引:
mysql> CREATE TABLE ordered_cache (
id INT PRIMARY KEY,
value INT,
INDEX USING BTREE (value)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
索引选择建议:
+——————-+————————+
| 场景 | 推荐索引类型 |
+——————-+————————+
| 等值查询 | HASH |
| 范围查询 | BTREE |
| 排序查询 | BTREE |
| 模糊查询 | BTREE |
+——————-+————————+
3. 数据类型支持
支持的数据类型:
– 整数类型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
– 浮点类型:FLOAT, DOUBLE
– 定点类型:DECIMAL
– 字符类型:CHAR, VARCHAR
– 时间类型:DATE, TIME, DATETIME, TIMESTAMP, YEAR
– 其他类型:ENUM, SET, JSON
不支持的数据类型:
– BLOB
– TEXT
– GEOMETRY
创建示例:
mysql> CREATE TABLE config_cache (
id INT PRIMARY KEY,
name VARCHAR(100),
value VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 内存分配
查看内存使用:
mysql> SHOW VARIABLES LIKE ‘max_heap_table_size’;
输出示例:
+———————+———-+
| Variable_name | Value |
+———————+———-+
| max_heap_table_size | 16777216 |
+———————+———-+
计算内存使用:
mysql> SELECT
TABLE_NAME,
TABLE_ROWS,
DATA_LENGTH + INDEX_LENGTH AS total_bytes,
(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 AS total_mb
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
输出示例:
+—————+————+————-+———-+
| TABLE_NAME | TABLE_ROWS | total_bytes | total_mb |
+—————+————+————-+———-+
| session_cache| 1000 | 1048576 | 1.00 |
+—————+————+————-+———-+
5. 表级锁
查看锁状态:
mysql> SHOW OPEN TABLES WHERE In_use > 0;
输出示例:
+—————+—————+——–+————-+
| Database | Table | In_use | Name_locked |
+—————+—————+——–+————-+
| production_db | session_cache | 1 | 0 |
+—————+—————+——–+————-+
锁竞争监控:
mysql> SHOW STATUS LIKE ‘Table_locks%’;
输出示例:
+———————–+——-+
| Variable_name | Value |
+———————–+——-+
| Table_locks_immediate | 10000 |
| Table_locks_waited | 5 |
+———————–+——-+
1.3 内存表特性
内存表具有独特的特性需要了解:
1. 数据持久性
特点:数据不持久化,重启后丢失
验证数据丢失:
mysql> INSERT INTO session_cache VALUES (‘test’, 1, NOW(), NOW(), NULL);
输出示例:
Query OK, 1 row affected (0.00 sec)
mysql> SELECT COUNT(*) FROM session_cache;
输出示例:
+———-+
| COUNT(*) |
+———-+
| 1 |
+———-+
重启MySQL后:
mysql> SELECT COUNT(*) FROM session_cache;
输出示例:
+———-+
| COUNT(*) |
+———-+
| 0 |
+———-+
解决方案:
– 使用触发器同步到磁盘表
– 定期备份到磁盘表
– 启动时重新加载数据
2. 表结构持久性
特点:表结构持久化,重启后保留
查看表定义文件:
ls -la /var/lib/mysql/production_db/
输出示例:
-rw-r—– 1 mysql mysql 8558 Apr 1 10:00 session_cache.frm
-rw-r—– 1 mysql mysql 65 Apr 1 10:00 session_cache.MYD
表结构保留:
mysql> SHOW CREATE TABLE session_cache\G
输出示例:
*************************** 1. row ***************************
Table: session_cache
Create Table: CREATE TABLE `session_cache` (
`session_id` varchar(64) NOT NULL,
`user_id` int DEFAULT NULL,
…
PRIMARY KEY (`session_id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4
3. 固定长度行
特点:使用固定长度行格式
创建VARCHAR表:
mysql> CREATE TABLE fixed_length_test (
id INT,
name VARCHAR(100)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
查看行格式:
mysql> SHOW TABLE STATUS LIKE ‘fixed_length_test’\G
输出示例:
*************************** 1. row ***************************
Name: fixed_length_test
Engine: MEMORY
Version: 10
Row_format: Fixed
Avg_row_length: 107
内存使用计算:
– VARCHAR(100)占用100字节
– INT占用4字节
– 每行约107字节
4. 索引限制
HASH索引限制:
– 只支持等值查询
– 不支持范围查询
– 不支持排序
– 不支持部分匹配
示例:
mysql> CREATE TABLE hash_test (
id INT,
value INT,
INDEX USING HASH (value)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
等值查询(使用索引):
mysql> EXPLAIN SELECT * FROM hash_test WHERE value = 1;
输出示例:
+—-+————-+———–+——+—————+——-+———+——-+——+——-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+———–+——+—————+——-+———+——-+——+——-+
| 1 | SIMPLE | hash_test | ref | value | value | 5 | const | 1 | NULL |
+—-+————-+———–+——+—————+——-+———+——-+——+——-+
范围查询(不使用索引):
mysql> EXPLAIN SELECT * FROM hash_test WHERE value > 1;
输出示例:
+—-+————-+———–+——+—————+——+———+——+——+————-+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+—-+————-+———–+——+—————+——+———+——+——+————-+
| 1 | SIMPLE | hash_test | ALL | value | NULL | NULL | NULL | 1 | Using where |
+—-+————-+———–+——+—————+——+———+——+——+————-+
5. 并发控制
表级锁特性:
mysql> CREATE TABLE lock_test (id INT PRIMARY KEY) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
会话1:
mysql> INSERT INTO lock_test VALUES (1);
— 不提交,持有表锁
会话2:
mysql> INSERT INTO lock_test VALUES (2);
— 等待会话1释放锁
监控锁等待:
mysql> SHOW PROCESSLIST;
输出示例:
+—-+——+———–+——+———+——+——-+———————–+
| Id | User | Host | db | Command | Time | State | Info |
+—-+——+———–+——+———+——+——-+———————–+
| 1 | root | localhost | test | Sleep | 10 | | NULL |
| 2 | root | localhost | test | Query | 5 | Locked| INSERT INTO lock_test |
+—-+——+———–+——+———+——+——-+———————–+
Part02-生产环境规划与建议
2.1 内存表设计原则
合理的内存表设计是性能优化的基础:
1. 适用场景选择
适合使用内存表的场景:
– 会话管理
– 缓存数据
– 临时计算结果
– 高频访问配置
不适合使用内存表的场景:
– 需要持久化的数据
– 大数据量存储
– 需要事务支持
– 需要BLOB/TEXT类型
2. 内存容量规划
评估内存需求:
mysql> SELECT
TABLE_NAME,
TABLE_ROWS,
AVG_ROW_LENGTH,
DATA_LENGTH + INDEX_LENGTH AS total_bytes
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
输出示例:
+—————+————+————–+————-+
| TABLE_NAME | TABLE_ROWS | AVG_ROW_LENGTH| total_bytes |
+—————+————+————–+————-+
| session_cache| 1000 | 100| 100000 |
+—————+————+————–+————-+
设置内存限制:
vim /etc/my.cnf
[mysqld]
max_heap_table_size = 256M
重启MySQL:
systemctl restart mysqld
输出示例:
MySQL service restarted.
3. 索引设计原则
根据查询类型选择索引:
mysql> CREATE TABLE cache_with_index (
id INT PRIMARY KEY,
key_name VARCHAR(50),
key_value VARCHAR(200),
— 等值查询使用HASH
INDEX idx_name USING HASH (key_name),
— 范围查询使用BTREE
INDEX idx_value USING BTREE (key_value)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 数据类型选择
优化数据类型以减少内存使用:
mysql> CREATE TABLE optimized_cache (
id INT UNSIGNED, — 使用UNSIGNED节省空间
status TINYINT, — 使用最小类型
flag BOOLEAN, — 布尔类型
name VARCHAR(50), — 限制长度
created_at TIMESTAMP — 时间戳
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
5. 表大小限制
单表大小限制:
mysql> SET max_heap_table_size = 64*1024*1024;
输出示例:
Query OK, 0 rows affected (0.00 sec)
创建表时指定:
mysql> CREATE TABLE large_memory_table (
id INT PRIMARY KEY,
data VARCHAR(100)
) ENGINE=MEMORY
MAX_ROWS = 1000000;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2.2 内存表优化策略
制定合理的内存表优化策略:
1. 内存使用优化
监控内存使用:
mysql> SELECT
TABLE_SCHEMA,
TABLE_NAME,
ENGINE,
TABLE_ROWS,
DATA_LENGTH / 1024 / 1024 AS data_mb,
INDEX_LENGTH / 1024 / 1024 AS index_mb
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
输出示例:
+————–+—————+——–+————+———+———-+
| TABLE_SCHEMA | TABLE_NAME | ENGINE | TABLE_ROWS | data_mb | index_mb |
+————–+—————+——–+————+———+———-+
| production_db| session_cache | MEMORY | 1000 | 0.10 | 0.05 |
+————–+—————+——–+————+———+———-+
清理过期数据:
mysql> DELETE FROM session_cache
WHERE expire_time < NOW();
输出示例:
Query OK, 50 rows affected (0.00 sec)
2. 索引优化
选择正确的索引类型:
-- 等值查询场景
mysql> CREATE TABLE lookup_cache (
key VARCHAR(50) PRIMARY KEY,
value VARCHAR(200)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
— 范围查询场景
mysql> CREATE TABLE range_cache (
id INT PRIMARY KEY,
score INT,
INDEX idx_score USING BTREE (score)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
3. 并发优化
减少锁持有时间:
mysql> — 使用小事务
mysql> INSERT INTO cache_table VALUES (1, ‘data’);
mysql> — 立即提交
批量操作优化:
mysql> INSERT INTO cache_table VALUES
(1, ‘data1’),
(2, ‘data2’),
(3, ‘data3’);
输出示例:
Query OK, 3 rows affected (0.00 sec)
4. 数据同步策略
同步到磁盘表:
mysql> DELIMITER //
mysql> CREATE PROCEDURE sync_to_disk()
BEGIN
INSERT INTO session_disk
SELECT * FROM session_cache
ON DUPLICATE KEY UPDATE
user_id = VALUES(user_id),
expire_time = VALUES(expire_time);
END //
mysql> DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
设置定时同步:
mysql> CREATE EVENT sync_memory_to_disk
ON SCHEDULE EVERY 5 MINUTE
DO CALL sync_to_disk();
输出示例:
Query OK, 0 rows affected (0.01 sec)
5. 容量监控
创建监控视图:
mysql> CREATE VIEW v_memory_usage AS
SELECT
TABLE_SCHEMA,
TABLE_NAME,
TABLE_ROWS,
(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 AS size_mb,
max_heap_table_size / 1024 / 1024 AS max_size_mb
FROM information_schema.TABLES
CROSS JOIN (SELECT @@max_heap_table_size AS max_heap_table_size) t
WHERE ENGINE = ‘MEMORY’;
查询使用率:
mysql> SELECT * FROM v_memory_usage;
输出示例:
+————–+—————+————+———+————-+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS | size_mb | max_size_mb |
+————–+—————+————+———+————-+
| production_db| session_cache | 1000 | 0.15 | 16.00 |
+————–+—————+————+———+————-+
2.3 内存表监控
建立完善的内存表监控体系:
1. 监控内存使用
查看内存表状态:
mysql> SHOW TABLE STATUS WHERE Engine = ‘MEMORY’;
输出示例:
+—————+——–+———+————+——+—————-+————-+—————–+————–+———–+—————-+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment |
+—————+——–+———+————+——+—————-+————-+—————–+————–+———–+—————-+
| session_cache | MEMORY | 10 | Fixed | 1000 | 100 | 100000 | 16777216 | 50000 | 0 | NULL |
+—————+——–+———+————+——+—————-+————-+—————–+————–+———–+—————-+
2. 监控性能指标
查看表锁统计:
mysql> SHOW STATUS LIKE ‘Table_locks%’;
输出示例:
+———————–+——-+
| Variable_name | Value |
+———————–+——-+
| Table_locks_immediate | 10000 |
| Table_locks_waited | 5 |
+———————–+——-+
查看内存使用统计:
mysql> SHOW STATUS LIKE ‘Memory%’;
输出示例:
+—————————+———-+
| Variable_name | Value |
+—————————+———-+
| Memory_used | 10485760 |
| Memory_used_by_memory_db | 1048576 |
+—————————+———-+
3. 监控表大小
创建监控脚本:
vim /opt/mysql/scripts/memory_table_monitor.sh
脚本内容:
#!/bin/bash
mysql -u monitor -p -N -e ”
SELECT
TABLE_NAME,
TABLE_ROWS,
(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 AS size_mb
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’
AND TABLE_SCHEMA = ‘production_db’
” > /tmp/memory_tables.txt
while read TABLE_NAME TABLE_ROWS SIZE_MB; do
if [ $(echo “$SIZE_MB > 10” | bc) -eq 1 ]; then
echo “Warning: $TABLE_NAME size is ${SIZE_MB}MB” | \
mail -s “Memory Table Size Alert” dba@company.com
fi
done < /tmp/memory_tables.txt
设置定时任务:
*/5 * * * * /opt/mysql/scripts/memory_table_monitor.sh
输出示例:
crontab: installing new crontab
4. 监控数据丢失
检查重启后数据:
mysql> SELECT COUNT(*) FROM session_cache;
输出示例:
+———-+
| COUNT(*) |
+———-+
| 0 |
+———-+
自动恢复数据:
mysql> DELIMITER //
mysql> CREATE PROCEDURE restore_memory_data()
BEGIN
INSERT INTO session_cache
SELECT * FROM session_backup
WHERE expire_time > NOW();
END //
mysql> DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
5. 告警配置
创建告警视图:
mysql> CREATE VIEW v_memory_alerts AS
SELECT
TABLE_NAME,
TABLE_ROWS,
(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 AS size_mb,
CASE
WHEN (DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 > 100 THEN ‘CRITICAL’
WHEN (DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 > 50 THEN ‘WARNING’
ELSE ‘OK’
END AS status
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
查询告警:
mysql> SELECT * FROM v_memory_alerts WHERE status != ‘OK’;
输出示例:
+—————+————+———-+———-+
| TABLE_NAME | TABLE_ROWS | size_mb | status |
+—————+————+———-+———-+
| large_cache | 50000 | 75.50 | WARNING |
+—————+————+———-+———-+
Part03-生产环境项目实施方案
3.1 内存表实施规范
制定内存表实施规范确保一致性:
1. 内存表创建规范
标准内存表模板:
mysql> CREATE TABLE cache_standard (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
cache_key VARCHAR(64) NOT NULL,
cache_value VARCHAR(2000),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expire_at TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uk_cache_key (cache_key),
KEY idx_expire (expire_at)
) ENGINE=MEMORY
MAX_ROWS = 100000
COMMENT ‘标准缓存表模板’;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 命名规范
命名约定:
+——————-+————————+
| 类型 | 命名规则 |
+——————-+————————+
| 会话缓存 | session_cache |
| 配置缓存 | config_cache |
| 临时数据 | temp_data |
| 查询缓存 | query_cache |
+——————-+————————+
3. 备份策略
创建备份表:
mysql> CREATE TABLE session_backup (
LIKE session_cache
) ENGINE=InnoDB;
输出示例:
Query OK, 0 rows affected (0.02 sec)
定时备份:
mysql> CREATE EVENT backup_memory_tables
ON SCHEDULE EVERY 1 MINUTE
DO
INSERT INTO session_backup
SELECT * FROM session_cache
ON DUPLICATE KEY UPDATE
user_id = VALUES(user_id),
expire_time = VALUES(expire_time);
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 恢复策略
启动时恢复数据:
mysql> DELIMITER //
mysql> CREATE PROCEDURE restore_all_memory_tables()
BEGIN
— 恢复会话缓存
TRUNCATE TABLE session_cache;
INSERT INTO session_cache
SELECT * FROM session_backup
WHERE expire_at > NOW();
SELECT ‘Memory tables restored’ AS status;
END //
mysql> DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
5. 监控规范
创建监控表:
mysql> CREATE TABLE memory_table_stats (
id INT AUTO_INCREMENT PRIMARY KEY,
table_name VARCHAR(100),
table_rows INT,
size_mb DECIMAL(10,2),
collect_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
输出示例:
Query OK, 0 rows affected (0.02 sec)
定时收集统计:
mysql> CREATE EVENT collect_memory_stats
ON SCHEDULE EVERY 5 MINUTE
DO
INSERT INTO memory_table_stats (table_name, table_rows, size_mb)
SELECT
TABLE_NAME,
TABLE_ROWS,
(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
输出示例:
Query OK, 0 rows affected (0.01 sec)
3.2 内存表应用场景
内存表在特定场景下有独特优势:
1. 会话管理
创建会话表:
mysql> CREATE TABLE user_session (
session_id VARCHAR(64) PRIMARY KEY,
user_id INT UNSIGNED,
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_active TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
expire_time TIMESTAMP,
ip_address VARCHAR(45),
user_agent VARCHAR(500),
data JSON
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
会话操作:
— 创建会话
mysql> INSERT INTO user_session
(session_id, user_id, expire_time, ip_address)
VALUES
(UUID(), 1, DATE_ADD(NOW(), INTERVAL 30 MINUTE), ‘192.168.1.1’);
输出示例:
Query OK, 1 row affected (0.00 sec)
— 验证会话
mysql> SELECT * FROM user_session
WHERE session_id = ‘abc123’
AND expire_time > NOW();
输出示例:
+———————————-+———+———————+———————+———————+————+————+——+
| session_id | user_id | login_time | last_active | expire_time | ip_address | user_agent | data |
+———————————-+———+———————+———————+———————+————+————+——+
| abc123 | 1 | 2026-04-01 10:00:00 | 2026-04-01 10:00:00 | 2026-04-01 10:30:00 | 192.168.1.1| NULL | NULL |
+———————————-+———+———————+———————+———————+————+————+——+
— 清理过期会话
mysql> DELETE FROM user_session WHERE expire_time < NOW();
输出示例:
Query OK, 10 rows affected (0.00 sec)
2. 配置缓存
创建配置缓存表:
mysql> CREATE TABLE config_cache (
config_key VARCHAR(100) PRIMARY KEY,
config_value VARCHAR(2000),
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
加载配置:
mysql> INSERT INTO config_cache (config_key, config_value)
SELECT config_key, config_value
FROM config_table;
输出示例:
Query OK, 100 rows affected (0.00 sec)
读取配置:
mysql> SELECT config_value FROM config_cache WHERE config_key = ‘site_name’;
输出示例:
+————–+
| config_value |
+————–+
| My Website |
+————–+
3. 查询结果缓存
创建查询缓存表:
mysql> CREATE TABLE query_cache (
cache_key VARCHAR(64) PRIMARY KEY,
cache_result JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expire_at TIMESTAMP,
INDEX idx_expire (expire_at)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
缓存查询结果:
mysql> INSERT INTO query_cache (cache_key, cache_result, expire_at)
VALUES (
MD5(‘SELECT * FROM products WHERE category = 1’),
(SELECT JSON_ARRAYAGG(JSON_OBJECT(‘id’, id, ‘name’, name))
FROM products WHERE category = 1),
DATE_ADD(NOW(), INTERVAL 5 MINUTE)
);
输出示例:
Query OK, 1 row affected (0.01 sec)
读取缓存:
mysql> SELECT cache_result FROM query_cache
WHERE cache_key = MD5(‘SELECT * FROM products WHERE category = 1’)
AND expire_at > NOW();
输出示例:
+———————————————————-+
| cache_result |
+———————————————————-+
| [{“id”: 1, “name”: “Product 1”}, {“id”: 2, “name”: …}] |
+———————————————————-+
4. 计数器
创建计数器表:
mysql> CREATE TABLE page_counter (
page_id INT PRIMARY KEY,
view_count INT UNSIGNED DEFAULT 0,
last_view TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
更新计数:
mysql> INSERT INTO page_counter (page_id, view_count)
VALUES (1, 1)
ON DUPLICATE KEY UPDATE
view_count = view_count + 1;
输出示例:
Query OK, 1 row affected (0.00 sec)
查询计数:
mysql> SELECT view_count FROM page_counter WHERE page_id = 1;
输出示例:
+————+
| view_count |
+————+
| 100 |
+————+
5. 排行榜
创建排行榜表:
mysql> CREATE TABLE leaderboard (
user_id INT PRIMARY KEY,
score INT UNSIGNED,
rank_position INT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_score USING BTREE (score DESC)
) ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
更新分数:
mysql> INSERT INTO leaderboard (user_id, score)
VALUES (1, 1000)
ON DUPLICATE KEY UPDATE score = score + 100;
输出示例:
Query OK, 1 row affected (0.00 sec)
查询排行榜:
mysql> SELECT user_id, score FROM leaderboard
ORDER BY score DESC
LIMIT 10;
输出示例:
+———+——-+
| user_id | score |
+———+——-+
| 5 | 5000 |
| 3 | 4500 |
| 1 | 4100 |
+———+——-+
3.3 内存表维护
内存表维护是长期运营的重要工作:
1. 定期清理
清理过期数据:
mysql> DELETE FROM session_cache WHERE expire_time < NOW();
输出示例:
Query OK, 50 rows affected (0.00 sec)
创建自动清理任务:
mysql> CREATE EVENT clean_expired_sessions
ON SCHEDULE EVERY 1 MINUTE
DO DELETE FROM session_cache WHERE expire_time < NOW();
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 数据重建
重建内存表:
mysql> ALTER TABLE session_cache ENGINE=MEMORY;
输出示例:
Query OK, 0 rows affected (0.01 sec)
优化表:
mysql> OPTIMIZE TABLE session_cache;
输出示例:
+—————————–+———-+———-+———-+
| Table | Op | Msg_type | Msg_text |
+—————————–+———-+———-+———-+
| production_db.session_cache | optimize | status | OK |
+—————————–+———-+———-+———-+
3. 内存监控
查看内存使用:
mysql> SELECT
TABLE_NAME,
TABLE_ROWS,
(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024 AS size_mb
FROM information_schema.TABLES
WHERE ENGINE = ‘MEMORY’;
输出示例:
+—————+————+———-+
| TABLE_NAME | TABLE_ROWS | size_mb |
+—————+————+———-+
| session_cache | 1000 | 0.15 |
+—————+————+———-+
4. 容量扩展
增加内存限制:
mysql> SET GLOBAL max_heap_table_size = 512*1024*1024;
输出示例:
Query OK, 0 rows affected (0.00 sec)
重建表以应用新限制:
mysql> ALTER TABLE session_cache ENGINE=MEMORY;
输出示例:
Query OK, 1000 rows affected (0.01 sec)
5. 备份恢复
备份内存表数据:
mysql> CREATE TABLE session_backup_20260401 AS
SELECT * FROM session_cache;
输出示例:
Query OK, 1000 rows affected (0.02 sec)
恢复数据:
mysql> INSERT INTO session_cache
SELECT * FROM session_backup_20260401;
输出示例:
Query OK, 1000 rows affected (0.01 sec)
Part04-生产案例与实战讲解
4.1 会话管理案例
以下是使用内存表进行会话管理的实战案例:
# 案例:高并发会话管理
# 问题描述:
# 需要处理每秒10000次会话验证请求
# 步骤1:创建会话表
mysql> CREATE TABLE user_session (
session_id VARCHAR(64) PRIMARY KEY,
user_id INT UNSIGNED,
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expire_time TIMESTAMP,
data JSON,
INDEX idx_user (user_id)
) ENGINE=MEMORY;
# 输出示例:
# Query OK, 0 rows affected (0.01 sec)
# 步骤2:创建会话操作存储过程
mysql> DELIMITER //
mysql> CREATE PROCEDURE create_session(
IN p_user_id INT,
OUT p_session_id VARCHAR(64)
)
BEGIN
SET p_session_id = UUID();
INSERT INTO user_session
(session_id, user_id, expire_time)
VALUES
(p_session_id, p_user_id,
DATE_ADD(NOW(), INTERVAL 30 MINUTE));
END //
mysql> CREATE PROCEDURE validate_session(
IN p_session_id VARCHAR(64),
OUT p_valid BOOLEAN,
OUT p_user_id INT
)
BEGIN
SELECT user_id INTO p_user_id
FROM user_session
WHERE session_id = p_session_id
AND expire_time > NOW();
SET p_valid = (p_user_id IS NOT NULL);
END //
mysql> DELIMITER ;
# 输出示例:
# Query OK, 0 rows affected (0.01 sec)
# 步骤3:测试性能
mysql> CALL create_session(1, @sid);
mysql> SELECT @sid;
# 输出示例:
# +————————————–+
# | @sid |
# +————————————–+
# | 550e8400-e29b-41d4-a716-446655440000 |
# +————————————–+
mysql> CALL validate_session(@sid, @valid, @uid);
mysql> SELECT @valid, @uid;
# 输出示例:
# +——–+——+
# | @valid | @uid |
# +——–+——+
# | 1 | 1 |
# +——–+——+
# 步骤4:性能测试结果
# +——————+————+
# | 操作 | QPS |
# +——————+————+
# | 创建会话 | 15000 |
# | 验证会话 | 50000 |
# +——————+————+
4.2 缓存加速案例
以下是使用内存表进行缓存加速的实战案例:
# 案例:配置缓存加速
# 问题描述:
# 配置查询频繁,磁盘IO压力大
# 步骤1:创建配置缓存表
mysql> CREATE TABLE config_cache (
config_key VARCHAR(100) PRIMARY KEY,
config_value TEXT,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=MEMORY;
# 输出示例:
# Query OK, 0 rows affected (0.01 sec)
# 步骤2:加载配置数据
mysql> INSERT INTO config_cache (config_key, config_value)
SELECT config_key, config_value
FROM config_table;
# 输出示例:
# Query OK, 100 rows affected (0.00 sec)
# 步骤3:创建缓存刷新存储过程
mysql> DELIMITER //
mysql> CREATE PROCEDURE refresh_config_cache()
BEGIN
— 清空缓存
TRUNCATE TABLE config_cache;
— 重新加载
INSERT INTO config_cache (config_key, config_value)
SELECT config_key, config_value
FROM config_table;
SELECT ROW_COUNT() AS refreshed_rows;
END //
mysql> DELIMITER ;
# 输出示例:
# Query OK, 0 rows affected (0.01 sec)
# 步骤4:性能对比
# 查询磁盘表:
mysql> SELECT config_value FROM config_table WHERE config_key = ‘site_name’;
# 执行时间:5ms
# 查询内存表:
mysql> SELECT config_value FROM config_cache WHERE config_key = ‘site_name’;
# 执行时间:0.1ms
# 性能提升:50倍
4.3 性能优化案例
以下是内存表性能优化的实战案例:
# 案例:排行榜性能优化
# 问题描述:
# 实时排行榜查询性能差
# 步骤1:创建内存排行榜表
mysql> CREATE TABLE leaderboard_memory (
user_id INT PRIMARY KEY,
score INT UNSIGNED,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_score USING BTREE (score DESC)
) ENGINE=MEMORY;
# 输出示例:
# Query OK, 0 rows affected (0.01 sec)
# 步骤2:同步数据
mysql> INSERT INTO leaderboard_memory (user_id, score)
SELECT user_id, score FROM leaderboard_disk;
# 输出示例:
# Query OK, 100000 rows affected (0.50 sec)
# 步骤3:查询排行榜
mysql> SELECT user_id, score FROM leaderboard_memory
ORDER BY score DESC
LIMIT 100;
# 输出示例:
# +———+——-+
# | user_id | score |
# +———+——-+
# | 12345 | 99999 |
# | 67890 | 99998 |
# +———+——-+
# 步骤4:性能对比
# +——————+————+
# | 存储引擎 | 查询时间 |
# +——————+————+
# | InnoDB | 50ms |
# | MEMORY | 1ms |
# +——————+————+
# 性能提升:50倍
# 步骤5:设置定时同步
mysql> CREATE EVENT sync_leaderboard
ON SCHEDULE EVERY 1 MINUTE
DO
INSERT INTO leaderboard_memory (user_id, score)
SELECT user_id, score FROM leaderboard_disk
ON DUPLICATE KEY UPDATE score = VALUES(score);
# 输出示例:
# Query OK, 0 rows affected (0.01 sec)
Part05-风哥经验总结与分享
5.1 内存表最佳实践
以下是MySQL内存表的最佳实践:
1. 设计原则
– 选择合适的应用场景
– 合理设置内存限制
– 选择正确的索引类型
– 优化数据类型
2. 性能原则
– 利用HASH索引加速等值查询
– 利用BTREE索引支持范围查询
– 减少锁持有时间
– 批量操作减少开销
3. 可靠性原则
– 定期备份到磁盘表
– 设置自动恢复机制
– 监控内存使用
– 设置容量告警
4. 维护原则
– 定期清理过期数据
– 监控表大小
– 及时扩展容量
– 保持数据同步
5.2 内存表限制
以下是MySQL内存表的主要限制:
1. 数据持久性限制
– 重启后数据丢失
– 需要备份机制
– 需要恢复策略
2. 数据类型限制
– 不支持BLOB类型
– 不支持TEXT类型
– 不支持GEOMETRY类型
– VARCHAR按最大长度存储
3. 功能限制
– 不支持事务
– 不支持外键
– 不支持行级锁
– 不支持全文索引
4. 容量限制
– 受max_heap_table_size限制
– 受系统内存限制
– 单表最大约4GB
5. 并发限制
– 表级锁
– 写操作阻塞读操作
– 高并发写入性能下降
5.3 内存表检查清单
以下是MySQL内存表的检查清单:
1. 设计阶段检查
[ ] 是否选择了合适的应用场景
[ ] 是否评估了内存需求
[ ] 是否选择了正确的索引类型
[ ] 是否优化了数据类型
2. 开发阶段检查
[ ] 是否设置了内存限制
[ ] 是否创建了备份机制
[ ] 是否实现了恢复策略
[ ] 是否测试了性能
3. 运维阶段检查
[ ] 是否监控了内存使用
[ ] 是否设置了容量告警
[ ] 是否定期清理过期数据
[ ] 是否保持数据同步
4. 监控阶段检查
[ ] 是否监控了表大小
[ ] 是否监控了锁等待
[ ] 是否监控了查询性能
[ ] 是否生成了分析报告
风哥提示:内存表是MySQL中一种特殊的表类型,适合存储临时数据和高频访问的缓存数据。由于数据存储在内存中,访问速度极快,但重启后数据会丢失。使用内存表时要注意选择正确的索引类型:HASH索引用于等值查询,BTREE索引用于范围查询和排序。建议建立完善的备份和恢复机制,确保数据安全。对于生产环境的内存表优化,务必在测试环境验证后再执行。更多视频教程请访问www.fgedu.net.cn
注意:本文档内容基于MySQL 8.4官方文档编写,适合DBA人员在学习和测试中使用。在生产环境中应用时,请务必进行充分的测试和验证。内存表数据不持久化,重启后会丢失,需要建立完善的备份恢复机制。文档中的命令和配置可能因MySQL版本不同而有所差异,请根据实际情况进行调整。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
