Mysql的详细知识点,看这一篇就够了

发布时间:2024年01月04日

?事物

? ?事物的4大特性

? ? ?在MySQL中,事务(Transaction)是指一组SQL语句的执行过程,该组SQL语句要么全部执行成功,要么全部执行失败,具有原子性、一致性、隔离性和持久性四个特性。

  • 原子性(Atomicity):事务中的所有操作要么全部完成,要么全部回滚,确保事务的操作是不可分割的单元,对数据库的状态的改变要么全部执行,要么全部不执行。

  • 一致性(Consistency):事务开始之前和事务结束之后,数据库的完整性约束没有被破坏。即事务的执行使得数据库从一个一致性状态转换到另一个一致性状态。

  • 隔离性(Isolation):事务的执行是相互隔离的,每个事务在执行过程中都不会被其他事务干扰。事务并发执行时,一个事务的中间结果不会被其他事务看到,每个事务都认为它是在系统中独立运行的。

  • 持久性(Durability):事务一旦提交,其结果将永久保存在数据库中,不会被回滚。即使在系统故障的情况下,通过数据库的重启或恢复操作也能够保证事务的持久性。

? ?事物的隔离级别

? ? ?在MySQL中,事务的隔离级别是指多个事务并发执行时,一个事务对数据的修改能否被其他事务看到。MySQL提供了四个隔离级别:

  • 读未提交(Read Uncommitted):最低的隔离级别,允许一个事务读取其他事务尚未提交的数据,可能出现脏读、不可重复读和幻读的问题。

  • 读已提交(Read Committed):允许一个事务读取其他事务已经提交的数据,避免了脏读的问题,但可能出现不可重复读和幻读的问题。

  • 可重复读(Repeatable Read):保证在同一个事务中多次读取同一数据时,读取的值是一致的。其他事务在该事务提交前对数据的修改不可见,避免了脏读和不可重复读的问题,但可能出现幻读的问题。

  • 串行化(Serializable):最高的隔离级别,强制事务串行执行,避免了脏读、不可重复读和幻读的问题,但可能导致并发性能降低。

? ? ? ? ? 隔离级别级别从低到高,事务的并发性能从高到低。在实际使用中,可根据业务需求和性能要求选择合适的隔离级别。默认情况下,MySQL的隔离级别是可重复读(Repeatable Read)。可以使用SET TRANSACTION ISOLATION LEVEL ...语句来设置事务的隔离级别。

? ?事物的分类

? ? ?在MySQL中,事务(Transaction)是一组已经被提交或者已经被回滚的SQL语句。事务是用来确保数据的一致性和完整性的一种机制。在MySQL中,事务可以分为以下几类:

  1. 隐式事务(Implicit Transaction):当没有明确启动事务语句(如BEGIN、START TRANSACTION)时,每个SQL语句都被视为一个单独的事务,默认情况下,MySQL自动提交每个SQL语句,即每个语句都被视为一个独立的事务。

  2. 显式事务(Explicit Transaction):明确使用BEGIN、START TRANSACTION等语句来启动事务,使用COMMIT语句来提交事务或使用ROLLBACK语句来回滚事务。显式事务可以包含多个SQL语句,并且在事务结束之前,所有的SQL语句都不会被提交或回滚。

  3. 自动提交事务(Autocommit Transaction):在MySQL中,默认情况下,每个SQL语句都会自动提交,也就是说,每个语句都被视为一个独立的事务。这意味着,如果没有明确使用事务语句来控制事务的边界,每个SQL语句都会立即执行,并且将结果持久化到数据库中。

  4. 手动提交事务(Manual Commit Transaction):通过显式的BEGIN、START TRANSACTION语句来启动事务,并通过使用COMMIT语句来手动提交事务。在手动提交事务的情况下,可以通过使用ROLLBACK语句来回滚事务。

? ? ? ? ?MySQL中的事务可以分为隐式事务和显式事务两种,而显式事务又可以分为自动提交事务和手动提交事务。隐式事务是默认的事务模式,而显式事务需要使用特定的语句来启动和控制事务的边界。手动提交事务提供了更高的灵活性,可以在事务执行过程中进行控制和处理。

? ?在MySQL中,锁是用于管理并发访问数据的机制。它们用于确保事务的一致性和隔离性。MySQL中的锁可以分为两类:锁定锁和非锁定锁。

? ?Lock

  1. 锁定锁(Locks): 锁定锁用于在对数据进行读写时保持数据的一致性和完整性。MySQL中的锁定锁包括共享锁(Shared Lock)和排他锁(Exclusive Lock)。

    • 共享锁(Shared Lock):也称为读锁,多个事务可以获取共享锁并同时读取相同的数据,但不能进行写操作。共享锁遵循"读-读"兼容原则,即读锁之间不互斥,多个事务可以同时持有读锁。

    • 排他锁(Exclusive Lock):也称为写锁,事务在对数据进行写操作时需要获取排他锁。排他锁遵循"写-写"互斥原则,多个事务不能同时持有写锁,读锁和写锁之间也是互斥的。

    下面是一个使用锁定锁的示例代码:

    -- 设置共享锁
    SELECT * FROM table_name LOCK IN SHARE MODE;
    
    -- 设置排他锁
    SELECT * FROM table_name FOR UPDATE;
    

    Latches

  2. 非锁定锁(Latches): Latch是MySQL内部使用的锁,用于保护内存数据结构的一致性。与锁定锁不同的是,非锁定锁是以非阻塞方式进行操作。非锁定锁主要用于保护共享内存及缓存数据结构。

? ? ? ? Consistent Lock Read

  1. 一致性的锁定读是指在事务执行期间,读取的数据会根据事务开始的时间点确定。即使其他事务正在对数据进行修改,一致性的锁定读仍然会读取事务开始时的数据版本。这可以确保事务的一致性和隔离性。

    下面是一个使用一致性的锁定读的示例代码:

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    START TRANSACTION;
    SELECT * FROM table_name;
    COMMIT;
    

? ? ?Consistent Non-locking Read

  1. 一致性的非锁定读(Consistent Non-locking Read): 一致性的非锁定读是指在事务执行期间,读取的数据不会被锁定,即使其他事务正在对数据进行修改。这可以提高并发性能,但可能会导致读取到不一致的数据。

  2. 下面是一个使用一致性的非锁定读的示例代码:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    START TRANSACTION;
    SELECT * FROM table_name;
    COMMIT;
    

? ? ? 死锁

  1. ?死锁(Deadlock): 死锁是指两个或多个事务互相等待对方释放资源而无法继续执行的情况。这种情况会导致事务无法完成并导致系统停滞。

    MySQL的InnoDB存储引擎使用死锁检测机制来避免死锁的发生。如果检测到死锁,InnoDB会选择一个事务作为死锁的牺牲者(victim),回滚该事务并释放锁资源,允许其他事务继续执行。

    下面是一个可能导致死锁的示例代码:

    -- 事务1
    START TRANSACTION;
    SELECT * FROM table1 WHERE id = 1 FOR UPDATE;
    
    -- 事务2
    START TRANSACTION;
    SELECT * FROM table2 WHERE id = 2 FOR UPDATE;
    
    -- 事务1继续执行
    UPDATE table2 SET column1 = 'value' WHERE id = 2;
    COMMIT;
    
    -- 事务2继续执行(由于事务1已经修改了table2的数据,事务2需要等待事务1的锁释放)
    UPDATE table1 SET column1 = 'value' WHERE id = 1;
    COMMIT;
    

以上是MySQL中锁、latch、一致性的锁定读、一致性的非锁定读和死锁的详细解释和说明。

mysql优化

SQL优化是提高数据库性能和查询效率的重要手段。下面是对于给出的几个优化原则

  1. 选择需要优化的SQL:首先需要确定哪些SQL语句需要进行性能优化。可以通过查看慢查询日志或者使用性能分析工具来找出频繁执行的查询语句。

  2. Explain和Profile入手:通过使用EXPLAIN命令可以分析查询语句的执行计划,帮助我们了解查询的执行过程以及可能存在的问题。通过使用PROFILE命令可以获取查询语句的详细执行信息,包括查询的资源消耗等。

    示例代码:

    EXPLAIN SELECT * FROM users WHERE age > 30;
    PROFILE SELECT * FROM users WHERE age > 30;
    
  3. 永远用小结果集驱动大的结果集:这个原则是指尽量减少内存的使用,尽量使用索引等方式来避免全表扫描。一般情况下,可以通过在WHERE子句中使用限制条件,使用合适的索引和使用分页等方式来实现。

    示例代码:

    SELECT * FROM users WHERE age > 30 LIMIT 10;
    
  4. 在索引中完成排序:如果查询需要对结果进行排序,尽量使用索引来完成排序操作,避免使用ORDER BY对大结果集进行排序。

    示例代码:

    SELECT * FROM users WHERE age > 30 ORDER BY name;
    
  5. 使用最小Columns:在查询时只选择需要的列,尽量避免使用SELECT *,这样可以减少网络传输和内存消耗。

    示例代码:

    SELECT name, age FROM users WHERE age > 30;
    
  6. 使用最有效的过滤条件:在WHERE子句中使用最有效的过滤条件,尽量避免使用不必要的条件,以提高查询效率。还可以使用合适的通配符和模糊查询方式。

    示例代码:

    SELECT * FROM users WHERE name LIKE 'J%';
    
  7. 避免复杂的JOIN和子查询:在查询中尽量避免使用复杂的JOIN和子查询,可以通过使用合适的索引来避免全表扫描,或者通过重构查询语句来减少查询复杂度。

    示例代码:

    SELECT * FROM users u INNER JOIN orders o ON u.id = o.user_id WHERE u.age > 30;
    

mqsql的执行流程

MySQL的执行流程可以大致分为以下7个步骤:

1、查询缓存(Query Cache):MySQL会先检查查询缓存,如果之前执行过相同的查询,并且结果还没有失效,则直接从缓存中返回结果,避免了重复的查询操作。

2、解析器生成解析树:如果查询不在查询缓存中,MySQL会使用解析器对SQL语句进行解析,生成解析树(parse tree)。

3、预处理再次生成解析树:MySQL会对解析树进行预处理,包括将视图展开、检查权限等操作,生成最终的解析树。

4、查询优化器(Query Optimizer):MySQL在生成解析树后,会使用查询优化器进行优化操作,目的是选择最优的执行计划。查询优化器会考虑多个因素,如索引的选择、连接操作的顺序等,以提高查询性能。

5、查询执行计划(Query Execution Plan):查询优化器输出的最优执行计划会被传递给查询执行引擎。执行计划是一个表示具体执行操作的树形结构,包括表的访问顺序、连接操作、使用的索引等。

6、查询执行引擎(Query Execution Engine):根据查询执行计划,查询执行引擎负责具体的查询操作。它会根据执行计划的指示,从磁盘加载数据的块到内存中,进行数据的过滤、排序、聚合等操作。

7、查询数据返回结果:当查询执行引擎完成查询操作后,将结果返回给客户端。客户端可以根据需要获取到的结果进行进一步的处理。

mysql表结构对性能的影响

  • 冗余数据的处理:冗余数据是指在数据库中存在多个副本或重复的数据。冗余数据会增加数据存储量、增加更新操作的复杂性,并且降低数据库的性能。? ? ? ? 提高系统的整体查询性能的方法是使用三范式(第一范式、第二范式和第三范式)进行数据规范化。三范式的核心思想是将数据拆分为多个表,每个表只包含一个主题的信息,并通过关系连接将这些表关联起来。这可以最大程度地避免重复数据,减少数据冗余,提高查询效率。
  • 大表拆小表:当一张表的数据量非常大时,数据库的查询效率可能会下降。为了提高性能,可以将大表拆分成多个小表。拆分表的依据可以是业务逻辑或者按照数据的访问频率进行拆分。这样可以减少单表的数据量,提高查询效率。
  • 根据需求展示更加合理的表结构:根据具体业务需求,设计合理的表结构可以提高查询性能。例如,对于频繁查询的字段,可以将其放到独立的表中,并通过外键与主表进行关联,从而减少查询的数据量。
  • 常用属性分离为小表:将常用的属性分离为小表可以提高查询性能。例如,可以将一个大表中的常用属性单独拆分成一个小表,并与主表通过主键关联。在查询时,只需要查询小表的数据,可以提高查询效率。

索引

在MySQL中,有不同类型的索引可以使用,包括B-Tree索引、哈希索引、全文索引和空间索引。

索引的类型

  1. B-Tree索引(默认索引类型):

    • B-Tree索引是最常见且最常用的索引类型。它适用于等值查询、范围查询和排序操作。
    • B-Tree索引使用二叉搜索树的原理,在每个节点上存储有序的索引值,以支持高效的查找和插入。
    • 可以在整数、字符串和日期等列上创建B-Tree索引。
  2. 哈希索引:

    • 哈希索引适用于精确匹配查询,即只能使用等值查询,不适用于范围查询和排序操作。
    • 哈希索引根据索引值的哈希码存储和查找数据。
    • 哈希索引在内存中进行操作,因此只适用于使用内存表的情况。
  3. 全文索引:

    • 全文索引适用于在文本列(如VARCHAR或TEXT)上进行全文搜索。
    • 全文索引可以搜索包含特定关键词的文本,而不仅仅是等值或范围匹配。
    • 全文索引使用一种称为倒排索引的数据结构来存储和快速搜索文本。
  4. 空间索引:

    • 空间索引适用于存储地理数据类型(如POINT、LINESTRING、POLYGON等)。
    • 空间索引支持空间数据的快速查找和查询。

方法创建索引

  1. 在创建表时添加索引:

    CREATE TABLE table_name (
        column1 data_type,
        column2 data_type,
        ...
        INDEX index_name (column1, column2, ...)
    );
    

  2. 使用ALTER TABLE添加索引:

    ALTER TABLE table_name ADD INDEX index_name (column1, column2, ...);
    

  3. 使用CREATE INDEX语句创建索引:

    CREATE INDEX index_name ON table_name (column1, column2, ...);
    

需要注意的是,为了获得最佳性能,应仅为经常使用于WHERE、JOIN、ORDER BY和GROUP BY等操作的列创建索引,不宜过度使用索引。

以下是一个示例,演示如何在MySQL中创建索引:

-- 创建具有B-Tree索引的表
CREATE TABLE customers (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    INDEX idx_age (age)
);

-- 使用ALTER TABLE添加哈希索引
ALTER TABLE customers ADD INDEX idx_name USING HASH (name);

-- 使用CREATE INDEX创建全文索引
CREATE FULLTEXT INDEX idx_description ON products (description);

-- 使用CREATE SPATIAL INDEX创建空间索引
CREATE SPATIAL INDEX idx_location ON locations (point);

以上示例中,"customers"表创建了一个B-Tree索引(idx_age),"customers"表使用ALTER TABLE添加了一个哈希索引(idx_name),"products"表使用CREATE INDEX创建了一个全文索引(idx_description),"locations"表使用CREATE SPATIAL INDEX创建了一个空间索引(idx_location)。

创建索引的条件和需要注意的事项如下

条件:

  1. 索引应该在频繁用作查询条件的列上创建,以提高查询性能。
  2. 索引应该在选择性高的列上创建,即列中有大量不同的值。
  3. 对于大表,应该优先考虑创建索引来优化查询性能。
  4. 可以对单个列或多个列创建索引,以支持联合查询。

事项:

  1. 不要过度索引:创建太多的索引会增加数据插入、更新和删除的开销,并且可能导致索引失效。
  2. 考虑索引的大小:创建索引会占用存储空间,尤其对于大表来说,需要考虑索引的大小对性能的影响。
  3. 注意联合索引的顺序:联合索引的顺序对查询的性能有影响,应该将选择性高的列放在联合索引的前面。
  4. 避免在查询条件中使用函数:使用函数会导致索引失效,应该尽量避免在查询条件中使用函数。
  5. 定期维护和优化索引:需要定期检查索引的使用情况,并根据需要进行重新创建、重建或删除索引,以保持索引的性能。

mysql当中join的实现原理

在 MySQL 中,JOIN 是用于将两个或多个表的数据按照指定的条件进行连接的操作。JOIN 操作的实现原理可以分为以下几个步骤:

  1. 解析查询语句:MySQL 首先会解析查询语句,确定需要连接的表以及连接条件。

  2. 执行连接操作:MySQL 将根据连接条件,将需要连接的表中的数据进行匹配。常见的 JOIN 类型包括 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 等。

    • INNER JOIN:只返回两个表中匹配的数据。

    • LEFT JOIN:返回左表中的所有数据,并包括右表中匹配的数据。

    • RIGHT JOIN:返回右表中的所有数据,并包括左表中匹配的数据。

    • FULL OUTER JOIN:返回左右表中的所有数据。

  3. 确定连接顺序:MySQL 会根据查询语句中的表的顺序以及连接条件的方向,确定连接的顺序。这个顺序通常是从最小的结果表开始,逐步将其他表与之连接。

  4. 执行连接操作:MySQL 通过遍历表中的数据,将满足连接条件的行进行匹配,以得到连接后的结果集。

  5. 返回结果集:MySQL 将连接后的结果集返回给用户。用户可以根据需要对结果集进行进一步的操作,如筛选、排序等。

? ? ?需要注意的是,JOIN 操作的性能会受到多个因素的影响,包括表的大小、索引的使用、连接条件的复杂度等。为了提高 JOIN 操作的性能,可以考虑使用适当的索引、优化查询语句以及合理设计表结构等措施。

执行计划与执行明细

在MySQL中,可以使用EXPLAIN来查看执行计划,以及使用SHOW PROFILES或者通过启用慢查询日志来查看执行明细。

  1. 执行计划(EXPLAIN): 执行计划用于展示MySQL优化器如何执行查询,并显示查询的执行顺序、使用的索引、扫描行数等信息。可以使用以下语法查看执行计划:
EXPLAIN SELECT * FROM table_name WHERE condition;

执行计划的输出结果包括以下列:

  • id:每个查询块的唯一标识符。
  • select_type:查询的类型,包括SIMPLE、PRIMARY、SUBQUERY、DERIVED等。
  • table:查询涉及的表。
  • partitions:查询涉及的分区。
  • type:访问表的方式,包括ALL(全表扫描)、index(使用索引扫描)、range(范围扫描)等。
  • possible_keys:可能使用的索引。
  • key:实际使用的索引。
  • key_len:使用索引的长度。
  • ref:与索引比较的列。
  • rows:扫描的行数。
  • filtered:结果集中满足条件的百分比。
  • Extra:额外的信息,如使用了临时表、使用了文件排序等。
  1. 执行明细(SHOW PROFILES和慢查询日志): 执行明细提供了查询的详细信息,包括执行时间、锁定时间、扫描行数等。可以使用SHOW PROFILES来查看最近执行的查询的执行明细,或者启用慢查询日志来记录执行明细。

使用SHOW PROFILES查看执行明细的步骤如下:

  • 执行SET profiling = 1;,启用查询性能分析。
  • 执行你要分析的查询。
  • 执行SHOW PROFILES;,显示查询的性能分析结果。
  • 执行SHOW PROFILE FOR QUERY x;(x为查询的id),显示具体的执行明细信息。

慢查询日志记录执行明细的步骤如下:

  • 在MySQL配置文件中(一般是my.cnf或my.ini)设置slow_query_log = 1,启用慢查询日志。
  • 设置long_query_time的值,表示执行时间超过多少秒的查询才会被记录。
  • 重启MySQL服务使配置生效。
  • 在慢查询日志文件中(一般是mysql-slow.log)查看记录的执行明细。

执行明细的一些重要参数含义如下:

  • Query_ID:查询的唯一标识符。
  • Duration:查询的执行时间。
  • Query_time:查询的实际运行时间。
  • Lock_time:查询的锁定时间。
  • Rows_examined:查询涉及的行数。
  • Rows_sent:查询返回的行数。
  • Rows_affected:查询影响的行数。
  • tmp_tables:使用的临时表数量。
  • tmp_disk_tables:使用的磁盘临时表数量。

文章来源:https://blog.csdn.net/Flying_Fish_roe/article/details/135380574
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。