MySQL优化:12种提升SQL实行效率的有用方法

打印 上一主题 下一主题

主题 904|帖子 904|积分 2712

在数据库管理和优化的世界里,MySQL作为一个盛行的关系型数据库管理系统,其性能优化是任何数据麋集型应用乐成的关键。优化MySQL数据库不但可以显著提高SQL查询的效率,还能确保数据的稳固性和可靠性。
在本文中,我将介绍12种提升SQL实行效率的有用方法,并通过实用的代码示例来详细展示怎样实施这些优化策略。
本文,已收录于,我的技能网站 ddkk.com,有大厂完备面经,工作技能,架构师成长之路,等经验分享
1、利用索引优化查询

利用场景:当你的数据库表中有大量数据,而你需要频仍进行搜刮查询时,索引是提高查询效率的关键。
代码示例
  1. -- 假设我们有一个员工表 employees
  2. CREATE TABLE employees (
  3.     id INT AUTO_INCREMENT,
  4.     name VARCHAR(100),
  5.     department_id INT,
  6.     PRIMARY KEY (id)
  7. );
  8. -- 为department_id字段创建索引
  9. CREATE INDEX idx_department ON employees(department_id);
  10. -- 使用索引进行查询
  11. SELECT * FROM employees WHERE department_id = 5;
复制代码
代码解释
第一步是创建一个包罗id, name, department_id字段的employees表。
然后为department_id字段创建一个索引idx_department。这个操纵会让基于department_id的查询更快。
最后,我们实行一个查询,利用创建的索引,从而提高查询效率。
最近无意间得到一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。这是大佬写的, 七千页的BAT大佬写的刷题笔记,让我offer拿到手软
2、优化查询语句

利用场景:制止利用高本钱的SQL操纵,如**SELECT ***,只管指定需要的列,减少数据传输和处理时间。
代码示例
  1. -- 不推荐的查询方式
  2. SELECT * FROM employees;
  3. -- 推荐的查询方式
  4. SELECT id, name FROM employees;
复制代码
代码解释
第一个查询语句利用了**SELECT ***,它会获取所有列,这在数据量大时非常低效。
第二个查询仅哀求需要的idname列,减少了数据处理的负担。
3、利用查询缓存

利用场景:当雷同的查询被频仍实行时,利用查询缓存可以制止重复的数据库扫描。
代码示例
  1. -- 启用查询缓存
  2. SET global query_cache_size = 1000000;
  3. SET global query_cache_type = 1;
  4. -- 执行查询
  5. SELECT name FROM employees WHERE department_id = 5;
复制代码
代码解释
通过设置query_cache_sizequery_cache_type,我们启用了查询缓存。
当我们实行查询时,MySQL会查抄缓存中是否已经有了该查询的结果,如果有,则直接返回结果,制止了重复的数据库扫描。
4、制止全表扫描

利用场景:当表中数据量巨大时,全表扫描会非常耗时。通过利用合适的查询条件来制止全表扫描,可以显著提高查询效率。
代码示例
  1. -- 假设我们需要查询员工表中特定部门的员工
  2. -- 不推荐的查询方式,会导致全表扫描
  3. SELECT * FROM employees WHERE name LIKE '%张%';
  4. -- 推荐的查询方式
  5. SELECT * FROM employees WHERE department_id = 3 AND name LIKE '%张%';
复制代码
代码解释
第一个查询利用了模糊匹配LIKE,但缺乏有用的过滤条件,大概导致全表扫描。
第二个查询在name字段的模糊匹配前,增加了对department_id的条件过滤,这样就可以先缩小查找范围,制止全表扫描。
5、利用JOIN取代子查询

利用场景:在需要关联多个表的复杂查询中,利用JOIN取代子查询可以提高查询效率。
代码示例
  1. -- 假设我们有一个部门表 departments
  2. CREATE TABLE departments (
  3.     id INT AUTO_INCREMENT,
  4.     name VARCHAR(100),
  5.     PRIMARY KEY (id)
  6. );
  7. -- 不推荐的子查询方式
  8. SELECT * FROM employees WHERE department_id IN (SELECT id FROM departments WHERE name = 'IT');
  9. -- 推荐的JOIN查询方式
  10. SELECT employees.* FROM employees JOIN departments ON employees.department_id = departments.id WHERE departments.name = 'IT';
复制代码
代码解释
第一个查询利用了子查询,这在实行时大概效率较低,特别是当子查询或主查询的结果集较大时。
第二个查询利用了JOIN操纵,这通常比子查询更有用,尤其是在处理大型数据集时。
6、公道分页

利用场景:在处理大量数据的列表展示时,公道的分页策略可以减少单次查询的负担,提高相应速度。
代码示例
  1. -- 假设我们需要分页显示员工信息
  2. -- 不推荐的分页方式,尤其是当offset值很大时
  3. SELECT * FROM employees LIMIT 10000, 20;
  4. -- 推荐的分页方式,使用更高效的条件查询
  5. SELECT * FROM employees WHERE id > 10000 LIMIT 20;
复制代码
代码解释
第一个查询利用了LIMIT和较大的偏移量offset,在大数据集上实行时会逐行扫描跳过大量记录,效率低下。
第二个查询通过在WHERE子句中添加条件来制止不必要的扫描,从而提高分页效率。
最近无意间得到一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。这是大佬写的, 七千页的BAT大佬写的刷题笔记,让我offer拿到手软
7、利用分区提高性能

利用场景:对于大型表,特别是那些行数以百万计的表,利用分区可以提高查询性能和数据管理效率。
代码示例
  1. -- 假设我们需要对一个大型的订单表 orders 进行分区
  2. CREATE TABLE orders (
  3.     order_id INT AUTO_INCREMENT,
  4.     order_date DATE,
  5.     customer_id INT,
  6.     amount DECIMAL(10, 2),
  7.     PRIMARY KEY (order_id)
  8. ) PARTITION BY RANGE ( YEAR(order_date) ) (
  9.     PARTITION p2020 VALUES LESS THAN (2021),
  10.     PARTITION p2021 VALUES LESS THAN (2022),
  11.     PARTITION p2022 VALUES LESS THAN (2023)
  12. );
  13. -- 查询特定年份的订单
  14. SELECT * FROM orders WHERE order_date BETWEEN '2021-01-01' AND '2021-12-31';
复制代码
代码解释
我们为orders表创建了基于order_date字段的年份范围分区。
查询特定年份的数据时,MySQL只会在相干分区中搜刮,提高了查询效率。
8、利用批处理减少I/O操纵

利用场景:在进行大量数据插入或更新时,批处理可以减少数据库的I/O操纵次数,从而提高性能。
代码示例
  1. -- 批量插入数据
  2. INSERT INTO employees (name, department_id)
  3. VALUES
  4.     ('张三', 1),
  5.     ('李四', 2),
  6.     ('王五', 3),
  7.     -- 更多记录
  8. ;
  9. -- 批量更新数据
  10. UPDATE employees
  11. SET department_id = CASE name
  12.     WHEN '张三' THEN 3
  13.     WHEN '李四' THEN 2
  14.     -- 更多条件
  15. END
  16. WHERE name IN ('张三', '李四', -- 更多名称);
复制代码
代码解释
在批量插入示例中,我们一次性插入多条记录,而不是对每条记录进行单独的插入操纵。
在批量更新示例中,我们利用CASE语句一次性更新多条记录,这比单独更新每条记录更有用率。
9、利用临时表优化复杂查询

利用场景:对于复杂的多步骤查询,利用临时表可以存储中间结果,从而简化查询并提高性能。
代码示例
  1. -- 创建一个临时表来存储中间结果
  2. CREATE TEMPORARY TABLE temp_employees
  3. SELECT department_id, COUNT(*) as emp_count
  4. FROM employees
  5. GROUP BY department_id;
  6. -- 使用临时表进行查询
  7. SELECT departments.name, temp_employees.emp_count
  8. FROM departments
  9. JOIN temp_employees ON departments.id = temp_employees.department_id;
复制代码
代码解释
起首,我们通过聚合查询创建了一个临时表temp_employees,用于存储每个部分的员工计数。
然后,我们将这个临时表与部分表departments进行连接查询,这样的查询通常比直接在原始表上实行复杂的聚合查询要高效。
10、优化数据范例

利用场景:在设计数据库表时,选择合适的数据范例对性能有显著影响。优化数据范例可以减少存储空间,提高查询效率。
代码示例
  1. -- 原始表结构
  2. CREATE TABLE example (
  3.     id INT AUTO_INCREMENT,
  4.     description TEXT,
  5.     created_at DATETIME,
  6.     is_active BOOLEAN,
  7.     PRIMARY KEY (id)
  8. );
  9. -- 优化后的表结构
  10. CREATE TABLE optimized_example (
  11.     id MEDIUMINT AUTO_INCREMENT,
  12.     description VARCHAR(255),
  13.     created_at DATE,
  14.     is_active TINYINT(1),
  15.     PRIMARY KEY (id)
  16. );
复制代码
代码解释
在原始表中,利用了INTTEXT这样的宽泛范例,这大概会占用更多的存储空间。
在优化后的表中,id字段改为MEDIUMINTdescription改为长度有限的VARCHAR(255)created_at只存储日期,而is_active利用**TINYINT(1)**来表示布尔值。这样的优化减少了每行数据的巨细,提高了存储效率。
11、制止利用函数和操纵符

利用场景:在WHERE子句中制止对列利用函数或操纵符,可以让MySQL更有用地利用索引。
代码示例
  1. -- 不推荐的查询方式,使用了函数
  2. SELECT * FROM employees WHERE YEAR(birth_date) = 1980;
  3. -- 推荐的查询方式
  4. SELECT * FROM employees WHERE birth_date BETWEEN '1980-01-01' AND '1980-12-31';
复制代码
代码解释
在第一个查询中,利用 YEAR() 函数会导致MySQL无法利用索引,因为它必须对每行数据应用函数。
第二个查询直接利用日期范围,这样MySQL可以有用利用birth_date字段的索引。
12、公道利用正规化和反正规化

利用场景:数据库设计中的正规化可以减少数据冗余,而反正规化可以提高查询效率。公道平衡这两者,可以得到最佳性能。
代码示例
  1. -- 正规化设计
  2. CREATE TABLE departments (
  3.     department_id INT AUTO_INCREMENT,
  4.     name VARCHAR(100),
  5.     PRIMARY KEY (department_id)
  6. );
  7. CREATE TABLE employees (
  8.     id INT AUTO_INCREMENT,
  9.     name VARCHAR(100),
  10.     department_id INT,
  11.     PRIMARY KEY (id),
  12.     FOREIGN KEY (department_id) REFERENCES departments(department_id)
  13. );
  14. -- 反正规化设计
  15. CREATE TABLE employees_denormalized (
  16.     id INT AUTO_INCREMENT,
  17.     name VARCHAR(100),
  18.     department_name VARCHAR(100),
  19.     PRIMARY KEY (id)
  20. );
复制代码
代码解释
在正规化设计中,departmentsemployees表被分开,减少了数据冗余,但大概需要JOIN操纵来获取完备信息。
在反正规化设计中,employees_denormalized表通过直接包罗部分信息来简化查询,提高读取性能,但大概会增加数据冗余和更新本钱。
项目文档&视频:

开源:项目文档 & 视频 Github-Doc
总结

以上提到的优化方法只是浩繁MySQL优化技能中的一小部分。在实际应用中,应根据详细的数据模式和查询需求机动选择最合适的优化策略。数据库优化是一个连续的过程,定期的性能评估和调优是保持数据库高效运行的关键。通过实践这些优化技巧,你可以显著提升数据库的性能和相应速度。
本文,已收录于,我的技能网站 ddkk.com,有大厂完备面经,工作技能,架构师成长之路,等经验分享

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表