=)、范围查询(>/<)和模糊查询(LIKE开头)-- 添加复合索引示例(用户表)
ALTER TABLE users
ADD INDEX idx_name_age (name, age);
-- 查询优化示例:精确匹配+范围查询
SELECT * FROM users
WHERE name = '张三' AND age BETWEEN 20 AND 30;CREATE FULLTEXT INDEX ft_content ON articles (title, content);CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT,
order_date DATE,
amount DECIMAL
) PARTITION BY RANGE (order_date) (
PARTITION p2023 VALUES LESS THAN ('2024-01-01'),
PARTITION p2024 VALUES LESS THAN ('2025-01-01')
);CREATE INDEX idx_user_full ON users (user_id, phone, email);
SELECT * FROM users WHERE user_id = 123 AND phone = '13800138000';ALTER TABLE logs
DROP INDEX idx_login_time,
ADD INDEX idx_login_time (login_time);EXPLAIN SELECT * FROM orders
WHERE user_id = 456 AND order_date > '2023-01-01';典型执行计划问题:
WHERE order_amount > 1000但索引是order_id)idx_user包含user_id和created_at,查询仅用user_id时未命中索引)原始查询:
SELECT product_id, SUM sales
FROM orders
WHERE user_id = 123
AND order_date >= '2023-01-01'
AND order_date < '2023-12-31'
GROUP BY product_id;执行计划问题:
GROUP BY时未创建覆盖索引优化方案:
-- 创建物化视图(存储计算结果)
CREATE MATERIALIZED VIEW mv_user_products AS
SELECT product_id, SUM(amount) AS sales
FROM orders
WHERE user_id = 123
AND order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY product_id
WITH CHECK OPTION;
-- 使用视图查询
SELECT * FROM mv_user_products;SET GLOBAL tx_isolation = 'READ COMMITTED';innodb_buffer_pool_size = 4G
innodb_flush_log_at_trx Commit = 1000 # 每笔事务日志刷新
innodb_log_file_size = 1GSELECT * FROM myisam_table LIMIT 1000, 5000;CREATE TABLE new_table SELECT * FROM old_table WHERE ...;
ALTER TABLE new_table ENGINE=InnoDB;[server]
type=master
address=127.0.0.1:3306
[client]
type=slave
address=127.0.0.1:3307wait_timeout = 600 # 默认8小时
interactive_timeout = 300 # 默认600秒SET GLOBAL query_cache_type = 1; # 启用查询缓存
SET GLOBAL query_cache_size = 256M; # 缓存大小适用场景:
log_bin_basename = /data/mysql binlog
binlog_row_format = mixedSELECT @row_count=0;
SELECT * FROM orders
WHERE user_id = 123
AND order_date >= '2023-01-01'
AND order_date < '2023-12-31'
LIMIT 1000, @row_count := @row_count + 100;graph TD
A[数据库响应慢] --> B{分析类型?}
B -->|写操作| C[检查事务锁]
B -->|读操作| D[查看慢查询日志]
C --> E[查看innodb_row_lock_time]
D --> F[分析执行计划]
F -->|索引缺失| G[添加合适索引]
F -->|连接过多| H[调整线程池大小]场景:电商促销期间订单查询响应时间从200ms飙升至5s
-- 执行计划分析发现索引缺失
ALTER TABLE orders ADD INDEX idx促销期 (user_id, created_at);
-- 优化存储引擎配置
innodb_buffer_pool_size = 8G
innodb_flush_log_at_trx = 1000
-- 查询缓存配置
query_cache_size = 512M
query_cache_limit = 5M
-- 启用自适应哈希索引(MySQL 8.0+)
innodb_adaptive_hash_index = ON错误示例:
CREATE INDEX idx_user ON users(user_id);
CREATE INDEX idx_user2 ON users(user_id, created_at);优化建议:
死锁案例:
-- 用户A执行
BEGIN;
SELECT * FROM orders WHERE user_id = 456 FOR UPDATE;
-- 用户B执行
SELECT * FROM orders WHERE user_id = 456 FOR UPDATE;解决方案:
SET TRANSACTION ISOLATION LEVEL READ COMMITTEDSET GLOBALinnodb Deadlock Detection = ON;innodb Deadlock Detect Interval = 300;错误分区:
CREATE TABLE logs (
log_id INT PRIMARY KEY,
user_id INT,
ip VARCHAR(15),
log_time DATETIME
) PARTITION BY RANGE (log_time);优化建议:
CREATE TABLE logs (
log_id INT PRIMARY KEY,
user_id INT,
ip VARCHAR(15),
log_time DATETIME
) PARTITION BY RANGE (log_time) (
PARTITION p2023 VALUES LESS THAN ('2024-01-01'),
PARTITION p2024 VALUES LESS THAN ('2025-01-01')
);innodb_buffer_pool_size = 4G
innodb_buffer_pool_type = hybrid
# 分配比例配置
[hybrid_buffer]
type=buffer_pool
size=2G
autoextend=ON
[hybrid_buffer2]
type=buffer_pool
size=2G
autoextend=ONxtrabackup --backup --target-dir=/backup --parallel=4STOP SLAVE;
SET GLOBAL仓促恢复=ON;
RECOVER TABLE orders;EXPLAIN ANNOTATE SELECT * FROM users WHERE id = 123;SHOW VARIABLES LIKE 'innodb%';innodb_buffer_pool_size = 50% of system memory innodb_max_dirty_pagesPer_latch = 1000 复制代码
SELECT ... INTO OUTFILE)LIMIT 0,10000)AUTO_INCREMENT配合SELECT FOR UPDATETRUNCATE TABLE orders;清空旧数据CREATE FULLTEXT INDEX idx_content ON articles (title, content);SHOW ENGINE INNODB STATUS监控锁状态SHOW processLIST分析连接瓶颈# 使用MySQL connector检查索引使用率
import mysql.connector
def check_index_usage():
cnx = mysql.connector.connect(user='root', password='1234', database='test')
cursor = cnx.cursor()
cursor.execute("SHOW INDEX FROM orders")
indexes = cursor.fetchall()
for idx in indexes:
if idx[2] == 'PRIMARY':
continue
cursor.execute("EXPLAIN SELECT * FROM orders WHERE %s = %s", (idx[4], idx[5]))
# 分析执行计划,标记未使用的索引ANALYZE TABLEALTER TABLE ... REBUILD INDEX)OPTIMIZE TABLECREATE TABLE logs (
id INT,
json_data JSON
) ENGINE=InnoDB;
SELECT * FROM logs WHERE JSON_CONTAINS_PATH(json_data, 'one', '$.user');SELECT
user_id,
COUNT(*) OVER (PARTITION BY user_id) as total_orders,
SUM(amount) OVER (PARTITION BY user_id) as spend
FROM orders
WHERE year(log_time) = 2023;BEGIN;
UPDATE products SET stock = stock - 1 WHERE id = 1;
UPDATE products SET stock = stock - 1 WHERE id = 2 AND user_id = 456;
COMMIT;-- 使用sysbench进行基准测试
sysbench/oltp/rnd读测试(对比有索引/无索引)
sysbench/oltp/rnd写测试(对比InnoDB/MyISAM)
测试结果示例:
| 场景 | 无优化 | 索引优化 | 存储引擎优化 |
|--------------|--------|----------|--------------|
| 平均查询时间 | 8s | 0.5s | 0.3s |
| 连接数峰值 | 1200 | 800 | 500 |
| I/O等待时间 | 65% | 18% | 12% |Q1:如何判断是否需要分区?
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT,
product_id INT,
order_date DATE
) PARTITION BY RANGE (order_date) (
PARTITION p2023 VALUES LESS THAN ('2024-01-01'),
PARTITION p2024 VALUES LESS THAN ('2025-01-01')
);Q2:如何解决慢查询日志分析结果中的重复问题?
EXPLAIN format=brief;到日志中SHOW ENGINE INNODB STATUS;查看锁等待情况SET GLOBAL slow_query_log = ON;并设置合适的阈值Q3:如何优化高并发写入场景?
InnoDB clustered index确保数据一致性innodb_buffer_pool_size(建议50-80%物理内存)INSERT ... SELECT预加载数据binlog_format = row减少日志体积SELECT * FROM mysql.query_cache_status;)SHOW ENGINE INNODB STATUS | grep buffer_pool)SELECT * FROM information_schema.innodb_locks;)EXPLAIN ANALYZE)SELECT * FROM mysql temptables;)covering index原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。