MySQL 常用函数性能优化指南(含索引影响分析)
以下是 MySQL 函数使用指南,新增性能影响评级、索引失效分析和优化方案,帮助您高效使用函数:
一、字符串处理函数(含性能分析)
函数 |
示例 |
性能影响 |
索引影响 |
优化建议 |
CONCAT() |
SELECT CONCAT(first_name, last_name) FROM users; |
⭐⭐ |
❌ 导致全扫描 |
存储计算列:ALTER TABLE users ADD full_name VARCHAR(100) AS (CONCAT(first_name, last_name)) STORED; |
SUBSTRING() |
SELECT * FROM logs WHERE SUBSTRING(url, 1, 5) = 'https'; |
⭐⭐⭐⭐ |
✅ 索引失效 |
改用前缀索引:ALTER TABLE logs ADD INDEX (url(5)); 后 WHERE url LIKE 'https%' |
UPPER()/LOWER() |
SELECT * FROM users WHERE LOWER(username) = 'admin'; |
⭐⭐⭐ |
✅ 索引失效 |
存储时统一大小写:INSERT INTO users (username) VALUES (LOWER('Admin')) |
GROUP_CONCAT() |
SELECT dept_id, GROUP_CONCAT(name) FROM emp GROUP BY dept_id; |
⭐⭐⭐ |
无影响 |
设置长度限制:GROUP_CONCAT(name SEPARATOR ',' ORDER BY id DESC LIMIT 100) |
JSON_EXTRACT() |
SELECT JSON_EXTRACT(data, '$.price') FROM products; |
⭐⭐ |
✅ 索引失效 |
MySQL 8.0+使用生成列:ALTER TABLE products ADD price DECIMAL(10,2) AS (JSON_EXTRACT(data, '$.price')) STORED; |
二、数值计算函数(含性能分析)
函数 |
示例 |
性能影响 |
索引影响 |
优化建议 |
ROUND() |
SELECT ROUND(price*0.9, 2) FROM products; |
⭐ |
❌ 小表无影响 |
大表避免实时计算,预计算存储 |
RAND() |
SELECT * FROM products ORDER BY RAND() LIMIT 5; |
⭐⭐⭐⭐⭐ |
✅ 全表扫描 |
改用ID范围随机:SELECT * FROM products WHERE id >= FLOOR(RAND()*MAX(id)) LIMIT 5; |
MOD() |
SELECT * FROM orders WHERE MOD(id, 10) = 0; |
⭐⭐⭐ |
✅ 索引失效 |
添加分区列:ALTER TABLE orders ADD part TINYINT AS (id%10) STORED, INDEX(part); |
GREATEST() |
UPDATE sales SET bonus = GREATEST(sales*0.1, 1000); |
⭐⭐ |
写操作无影响 |
批量更新分片执行 |
三、日期时间函数(含性能分析)
函数 |
示例 |
性能影响 |
索引影响 |
优化建议 |
DATE_FORMAT() |
SELECT * FROM orders WHERE DATE_FORMAT(create_time,'%Y-%m') = '2025-08'; |
⭐⭐⭐⭐ |
✅ 索引失效 |
改用范围查询:WHERE create_time BETWEEN '2025-08-01' AND '2025-08-31' |
YEAR()/MONTH() |
SELECT * FROM logs WHERE YEAR(create_time) = 2025; |
⭐⭐⭐ |
✅ 索引失效 |
存储计算列:ADD INDEX (create_year) |
DATE_ADD() |
SELECT * FROM events WHERE event_time > DATE_ADD(NOW(), INTERVAL -1 HOUR); |
⭐ |
✅ 索引有效 |
保持函数在比较符右侧:WHERE event_time > (NOW() - INTERVAL 1 HOUR) |
UNIX_TIMESTAMP() |
SELECT * FROM sessions WHERE UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time) > 3600; |
⭐⭐ |
✅ 索引失效 |
存储持续时间:ADD COLUMN duration INT AS (UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time)) STORED |
四、条件判断函数(含性能分析)
函数 |
示例 |
性能影响 |
索引影响 |
优化建议 |
IF() |
SELECT id, IF(status=1, '启用', '禁用') AS status_text FROM devices; |
⭐ |
❌ 无影响 |
可安全使用 |
CASE |
SELECT CASE WHEN score>90 THEN 'A' ... END FROM exams; |
⭐ |
❌ 无影响 |
复杂逻辑建议应用层处理 |
COALESCE() |
SELECT COALESCE(email, phone) AS contact FROM users; |
⭐⭐ |
❌ 无影响 |
避免在WHERE中使用:WHERE COALESCE(email,'') != '' → WHERE email IS NOT NULL |
IFNULL() |
SELECT IFNULL(discount, 0) FROM orders; |
⭐ |
❌ 无影响 |
可安全使用 |
五、聚合函数(含性能分析)
函数 |
示例 |
性能影响 |
索引影响 |
优化建议 |
COUNT() |
SELECT COUNT(DISTINCT user_id) FROM big_table; |
⭐⭐⭐⭐ |
✅ 全表扫描 |
用近似计数:SELECT COUNT(*) FROM (SELECT user_id FROM big_table GROUP BY user_id) tmp; |
AVG() |
SELECT AVG(salary) FROM employees WHERE dept=3; |
⭐⭐ |
✅ 索引有效 |
确保dept有索引,大表分片统计 |
GROUP_CONCAT() |
SELECT dept, GROUP_CONCAT(name) FROM emp GROUP BY dept; |
⭐⭐⭐ |
✅ 内存消耗 |
设置group_concat_max_len 限制长度 |
SUM() |
SELECT SUM(amount) FROM sales WHERE date>'2025-01-01'; |
⭐⭐ |
✅ 索引有效 |
添加覆盖索引:INDEX(date, amount) |
六、高级函数(含性能分析)
函数 |
示例 |
性能影响 |
索引影响 |
优化建议 |
ROW_NUMBER() |
SELECT id, ROW_NUMBER() OVER(ORDER BY score DESC) FROM students; |
⭐⭐⭐ |
❌ 无索引 |
MySQL 8.0+使用,避免大表全排序 |
CAST() |
SELECT * FROM products WHERE CAST(price AS UNSIGNED) > 1000; |
⭐⭐⭐⭐ |
✅ 索引失效 |
存储时使用正确类型,避免转换 |
UUID() |
INSERT INTO orders(id, ...) VALUES(UUID(), ...); |
⭐⭐ |
✅ 索引碎片 |
改用有序UUID:UUID_TO_BIN(UUID(), 1) |
FULLTEXT() |
SELECT * FROM articles WHERE MATCH(content) AGAINST('MySQL'); |
⭐⭐ |
✅ 专用索引 |
使用全文索引并优化配置 |
函数使用黄金法则
1. 索引失效高危场景
SELECT * FROM users WHERE DATE_FORMAT(create_time,'%Y%m') = '202508';
SELECT * FROM users WHERE create_time BETWEEN '2025-08-01' AND '2025-08-31';
2. 预计算策略
SELECT *, price*0.9 AS discount_price FROM products;
ALTER TABLE products ADD discount_price DECIMAL(10,2) AS (ROUND(price*0.9,2)) STORED;
CREATE INDEX idx_discount ON products(discount_price);
3. 函数执行成本分级
级别 |
特征 |
代表函数 |
⭐ |
轻量级 |
IF(), COALESCE() |
⭐⭐ |
中等 |
DATE_ADD(), CONCAT() |
⭐⭐⭐ |
较重 |
RAND(), GROUP_CONCAT() |
⭐⭐⭐⭐ |
高危 |
SUBSTRING(字段), CAST(字段) |
⭐⭐⭐⭐⭐ |
灾难 |
ORDER BY RAND() |
4. 优化检测工具
EXPLAIN SELECT * FROM users WHERE LOWER(username)='admin';
SET profiling = 1;
SELECT ...;
SHOW PROFILE FOR QUERY 1;
终极建议:
- WHERE条件中的列禁止使用函数
- ORDER BY/GROUP BY 避免复杂计算
- 大表查询使用预计算列+索引
- 高频计算逻辑移入应用层或存储过程
通过遵循这些规则,您能在享受函数便利性的同时,保持数据库的高性能运行!