谈谈:MySQL 优化与索引建立

98 阅读6分钟

在关系型数据库中,SQL 优化和索引建立是提高查询性能的重要手段。SQL 优化可以减少查询次数和查询时间,而索引建立则可以加速查询。

SQL 优化

SQL 语句的性能受多种因素影响,如查询条件、查询语句的组成、表结构等。下面介绍一些 SQL 优化的方法。

  1. 减少查询次数

一次性查询多条记录比多次查询单条记录要快,因为多次查询需要建立多次连接。因此,我们应该尽可能地减少查询次数,比如使用 UNION 或 JOIN 等操作,将多个查询合并为一个。

  1. 避免使用 SELECT *

查询所有字段会增加查询的开销,因为数据库需要检索所有字段并返回它们。我们应该只查询需要的字段,这样可以减少查询的开销和网络传输的数据量。

  1. 避免使用 HAVING 子句

HAVING 子句用于在 GROUP BY 子句之后筛选数据,它会对数据进行一次聚合操作,因此会增加查询的开销。我们应该尽量在 WHERE 子句中进行筛选,而不是在 HAVING 子句中。

  1. 使用 EXPLAIN 命令查看查询计划

EXPLAIN 命令可以显示查询的执行计划,包括使用的索引、表的访问顺序、使用的连接类型等。通过查看查询计划,我们可以确定查询是否使用了索引,以及如何优化查询。

索引建立

索引是一种数据结构,可以加速查询操作。在建立索引时,我们需要遵循最左原则。最左原则是指在建立联合索引时,应该先考虑使用最常用的字段,然后逐个考虑其他字段。下面介绍一些常用的索引数据结构。

B+ 树

B+ 树是一种平衡树,它的节点包含多个关键字和指向子节点的指针。B+ 树的叶子节点包含了所有的数据,而非叶子节点只包含关键字和指向子节点的指针。B+ 树的优点是查询效率高,因为每次查询只需要遍历一条从根节点到叶子节点的路径。

B+树数据结构及其工作原理

B+树是一种平衡的多路搜索树,广泛应用于数据库索引。B+树具有以下特点:

a. 所有叶子节点都位于同一层,这意味着查询性能稳定。

b. 叶子节点包含了所有键值,非叶子节点仅用于索引。

c. 叶子节点之间通过指针相互连接,便于范围查询。

B+树的高度相对较低,这意味着查询操作需要的磁盘I/O次数较少,从而提高查询性能。

B+树的工作原理如下:

  1. 查询:从根节点开始,根据键值与节点中的关键字进行比较,确定下一层要搜索的子节点,直到叶子节点。在叶子节点中找到目标键值,即完成查询。
  2. 插入:首先按照查询操作找到待插入的叶子节点位置,然后将新键值插入。如果叶子节点已满,需要进行分裂操作,并将分裂产生的新关键字插入到父节点中。如果父节点也满了,继续向上分裂,直至根节点。在极端情况下,可能需要增加树的高度。
  3. 删除:首先按照查询操作找到待删除的叶子节点位置,然后将目标键值删除。如果删除后叶子节点的关键字数量低于阈值,需要进行合并或者借关键字操作,以保持树的平衡。

最左原则

最左原则是指在创建联合索引时,查询条件需要遵循索引中列的顺序。例如,假设我们有一个包含三个列(A, B, C)的联合索引,那么以下查询将充分利用索引:

复制
SELECT * FROM table WHERE A = 1 AND B = 2 AND C = 3;

但是,以下查询将无法充分利用索引:

复制
SELECT * FROM table WHERE B = 2 AND C = 3;

在这种情况下,我们可以考虑创建一个新的索引,以便更好地满足查询需求。

最左原则指的是在 SQL 语句中,如果使用了联合索引,那么查询条件必须从联合索引的最左边开始。例如:

CREATE TABLE users (  
id INT PRIMARY KEY,  
name VARCHAR(50),  
age INT,  
gender VARCHAR(10)  
);

CREATE INDEX idx_users_name_age_gender ON users (name, age, gender);

SELECT * FROM users WHERE name = 'Alice' AND age = 25;  
SELECT * FROM users WHERE age = 25 AND name = 'Alice';

这两个 SQL 语句的查询条件是一样的,但是它们的顺序不同。根据最左原则,第一个 SQL 语句可以使用联合索引 idx_users_name_age_gender,而第二个 SQL 语句无法使用联合索引,只能使用 name 索引或者全表扫描。

那么为什么要遵循最左原则呢?因为联合索引是按照索引列的顺序建立的,查询条件如果不按照顺序来,就会导致索引失效,无法利用索引的优势,从而导致查询变慢。

除了最左原则之外,我们还需要注意以下几点:

  1. 尽量避免在查询条件中使用函数和表达式,因为这些无法使用索引优化。
    例如:
SELECT * FROM users WHERE YEAR(created_at) = 2021;  
SELECT * FROM users WHERE name LIKE '%Alice%';

这两个 SQL 语句都无法使用索引优化,因为 YEAR 函数和 LIKE 运算符都无法使用索引,会导致全表扫描。

  1. 尽量避免使用 OR 运算符,因为 OR 运算符也会导致索引失效,无法使用索引优化。
    例如:

SELECT * FROM users WHERE name = 'Alice' OR age = 25;

这个 SQL 语句无法使用联合索引 idx_users_name_age_gender,只能使用 name 索引或者全表扫描。

  1. 尽量避免使用 IN 和 NOT IN 运算符,因为它们也会导致索引失效,无法使用索引优化。
    例如:
SELECT * FROM users WHERE age IN (25, 30, 35);

这个 SQL 语句无法使用联合索引 idx_users_name_age_gender,只能使用 age 索引或者全表扫描。

总之,建立索引是优化 SQL 查询的重要手段之一,而最左原则是索引建立的重要原则之一。我们需要遵循最左原则,尽量避免使用函数、表达式、OR、IN 和 NOT IN 运算符,从而提高查询效率。

了解最左原则和B+树数据结构的工作原理对于优化SQL查询性能至关重要。通过合理地创建和使用索引,我们可以大大提高数据库查询性能