【MySQL是怎样运行的 | 第一篇】Explain执行计划上

news2024/11/15 7:30:28

在这里插入图片描述

文章目录

  • 1.查询优化-Explain语句详解上
    • 1.1前言
    • 1.2执行计划输出各列详解
      • 1.2.1 table
      • 1.2.2 id
      • 1.2.3 select_type
      • 1.2.4 partitions
      • 1.2.5 type
      • 1.2.6 possible_keys和key
      • 1.2.7 key_len
      • 1.2.8 ref
      • 1.2.9 rows
  • 世纪晚霞

1.查询优化-Explain语句详解上

1.1前言

  1. 一条查询语句在经过 MySQL 查询优化器的各种基于成本和规则的优化会后生成一个所谓的 执行计划 ,这个执行计划展示了接下来具体执行查询的方式,比如可能使用的索引、实际使用的索引、以及使用的索引长度
  2. 可以使用EXPLAIN 语句来帮助我们查看某个查询语句的具体执行计划,例如:
mysql> EXPLAIN SELECT 1;
+----+-------------+-------+------------+------+---------------+------+---------+------+--
----+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | r
ows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--
----+----------+----------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | N
ULL | NULL | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+--
----+----------+----------------+
1 row in set, 1 warning (0.01 sec)
  1. EXPLAIN 语句输出的各个列的作用:

    1. id: 在一个大的查询语句中每个 SELECT 关键字都对应一个唯一的 id
    2. select_type :SELECT 关键字对应的那个查询的类型
    3. table 表名
    4. partitions 匹配的分区信息
    5. type :针对单表的访问方法
    6. possible_keys :可能用到的索引
    7. key :实际上使用的索引
    8. key_len :实际使用到的索引长度
    9. ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息
    10. rows:预估的需要读取的记录条数
    11. filtered:某个表经过搜索条件过滤后剩余记录条数的百分比
    12. Extra 一些额外的信息
  2. 测试表:single_table表

  3. 我们仍然假设有两个和 single_table 表构造一模一样的 s1 、 s2 表,而且这两个表里边儿有10000条记录,除 id列外其余的列都插入随机值

CREATE TABLE single_table (
 id INT NOT NULL AUTO_INCREMENT,
 key1 VARCHAR(100),
 key2 INT,
 key3 VARCHAR(100),
 key_part1 VARCHAR(100),
 key_part2 VARCHAR(100),
 key_part3 VARCHAR(100),
 common_field VARCHAR(100),
 PRIMARY KEY (id),
 KEY idx_key1 (key1),
 UNIQUE KEY idx_key2 (key2),
 KEY idx_key3 (key3),
 KEY idx_key_part(key_part1, key_part2, key_part3)
) Engine=InnoDB CHARSET=utf8;

1.2执行计划输出各列详解

1.2.1 table

  1. 定EXPLAIN语句输出的每条记录都对应着某个单表的访问方法,该条记录的table列代表着该表 的表名

  2. 单表测试:只涉及对 s1 表的单表查询,所以 EXPLAIN 输出中只有一条记录

    mysql> EXPLAIN SELECT * FROM s1;
    +----+-------------+-------+------------+------+---------------+------+---------+------+--
    ----+----------+-------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | r
    ows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+--
    ----+----------+-------+
    | 1 | SIMPLE | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9
    688 | 100.00 | NULL |
    +----+-------------+-------+------------+------+---------------+------+---------+------+--
    ----+----------+-------+
    1 row in set, 1 warning (0.00 sec)
    
  3. 连接查询:到这个连接查询的执行计划中有两条记录,这两条记录的 table 列分别是 s1 和 s2 ,这两条记录用来分 别说明对 s1 表和 s2 表的访问方法是什么

    mysql> EXPLAIN SELECT * FROM s1 INNER JOIN s2;
    +----+-------------+-------+------------+------+---------------+------+---------+------+--
    ----+----------+---------------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | r
    ows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+--
    ----+----------+---------------------------------------+
    | 1 | SIMPLE | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9
    688 | 100.00 | NULL |
    | 1 | SIMPLE | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9
    954 | 100.00 | Using join buffer (Block Nested Loop) |
    +----+-------------+-------+------------+------+---------------+------+---------+------+--
    ----+----------+---------------------------------------+
    2 rows in set, 1 warning (0.01 sec)
    

1.2.2 id

  1. 查询语句中每出现一个 SELECT 关键字,MySQL 就会为它分配一个唯一的 id 值
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | ref | idx_key1 | idx_key1 | 303 | cons
t | 8 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
1 row in set, 1 warning (0.03 sec)
  1. 对于连接查询来说,一个 SELECT 关键字后边的 FROM 子句中可以跟随多个表,所以在连接查询的执行计划中,每个表都会对应一条记录,但是这些记录的id值都是相同的
mysql> EXPLAIN SELECT * FROM s1 INNER JOIN s2;
+----+-------------+-------+------------+------+---------------+------+---------+------+--
----+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | r
ows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--
----+----------+---------------------------------------+
| 1 | SIMPLE | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9
688 | 100.00 | NULL |
| 1 | SIMPLE | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9
954 | 100.00 | Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+--
----+----------+---------------------------------------+
2 rows in set, 1 warning (0.01 sec)
  1. 对于包含子查询的查询语句来说,就可能涉及多个 SELECT 关键字,所以在包含子查询的查询语句的执行计划 中,每个 SELECT 关键字都会对应一个唯一的 id 值
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2) OR key3 = 'a';
+----+-------------+-------+------------+-------+---------------+----------+---------+----
--+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+----------+---------+----
--+------+----------+-------------+
| 1 | PRIMARY | s1 | NULL | ALL | idx_key3 | NULL | NULL | NUL
L | 9688 | 100.00 | Using where |
| 2 | SUBQUERY | s2 | NULL | index | idx_key1 | idx_key1 | 303 | NUL
L | 9954 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+----------+---------+----
--+------+----------+-------------+
2 rows in set, 1 warning (0.02 sec)

1.2.3 select_type

  1. MySQL为每一个 SELECT 关键字代表的小查询都定义了一个称之为 select_type 的属性

  2. 作用:只要知道了某个小查询的 select_type 属性,就知道了这个小查询在整个大查询中扮演了一个什么角色

  3. 取值:

    1. SINPLE: 查询语句中不包含 UNION 或者子查询的查询都算作是 SIMPLE 类型

    2. PRIMARY: 对于包含 UNION 、 UNION ALL 或者子查询的大查询来说,它是由几个小查询组成的,最左边的小查询即为PRIMARY

    3. UNION: 对于包含 UNION 或者 UNION ALL 的大查询来说,它是由几个小查询组成的,其中除了最左边的那个小查询以 外,其余的小查询的 select_type 值就是 UNION

       mysql> EXPLAIN SELECT * FROM s1 UNION SELECT * FROM s2;
       +----+--------------+------------+------------+------+---------------+------+-------
      --+------+------+----------+-----------------+
       | id | select_type | table | partitions | type | possible_keys | key | key_le
      n | ref | rows | filtered | Extra |
       +----+--------------+------------+------------+------+---------------+------+-------
      --+------+------+----------+-----------------+
       | 1 | PRIMARY | s1 | NULL | ALL | NULL | NULL | NULL
      | NULL | 9688 | 100.00 | NULL |
       | 2 | UNION | s2 | NULL | ALL | NULL | NULL | NULL
      | NULL | 9954 | 100.00 | NULL |
       | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL
      | NULL | NULL | NULL | Using temporary |
       +----+--------------+------------+------------+------+---------------+------+-------
      --+------+------+----------+-----------------+
       3 rows in set, 1 warning (0.00 sec)
      
    4. UNION RESULT:MySQL 选择使用临时表来完成 UNION 查询的去重工作,针对该临时表的查询的 select_type 就是 UNION RESULT

    5. SUBQUERY: 如果包含子查询的查询语句不能够转为对应的 semi-join 的形式,并且该子查询是不相关子查询,并且查询 优化器决定采用将该子查询物化的方案来执行该子查询,该子查询的select_type就为 SUBQUERY

      mysql> EXPLAIN SELECT * FROM s1 WHERE key1 IN (SELECT key1 FROM s2) OR key3 = 'a';
       +----+-------------+-------+------------+-------+---------------+----------+--------
      -+------+------+----------+-------------+
       | id | select_type | table | partitions | type | possible_keys | key | key_len
      | ref | rows | filtered | Extra |
       +----+-------------+-------+------------+-------+---------------+----------+--------
      -+------+------+----------+-------------+
       | 1 | PRIMARY | s1 | NULL | ALL | idx_key3 | NULL | NULL
      | NULL | 9688 | 100.00 | Using where |
       | 2 | SUBQUERY | s2 | NULL | index | idx_key1 | idx_key1 | 303
      | NULL | 9954 | 100.00 | Using index |
       +----+-------------+-------+------------+-------+---------------+----------+--------
      -+------+------+----------+-------------+
       2 rows in set, 1 warning (0.00 sec)
      

      可以看到,外层查询的 select_type 就是 PRIMARY ,子查询的 select_type 就是 SUBQUERY 。需要大家注意 的是,由于select_type为SUBQUERY的子查询由于会被物化,所以只需要执行一遍

    6. DEPENDENT UNION:

    7. DERIVED

    8. MATERIALIZED

1.2.4 partitions

  1. 即分区:先不学习

1.2.5 type

  1. 执行计划的一条记录就代表着 MySQL 对某个表的执行查询时的访问方法

  2. 其中的 type 列就表明了 这个访问方法是个啥

  3. 对使用 InnoDB 存储引擎的表进行单表访问的一些访问方法,完整的访问方法如下: system , const , eq_ref , ref , fulltext , ref_or_null , index_merge , unique_subquery , index_subquery , range , index , ALL

  4. system: 当表中只有一条记录并且该表使用的存储引擎的统计数据是精确的,比如MyISAM、Memory,那么对该表的 访问方法就是 system

  5. const: 当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法 就是 const

    mysql> EXPLAIN SELECT * FROM s1 WHERE id = 5;
     +----+-------------+-------+------------+-------+---------------+---------+---------
    +-------+------+----------+-------+
     | id | select_type | table | partitions | type | possible_keys | key | key_len
    | ref | rows | filtered | Extra |
     +----+-------------+-------+------------+-------+---------------+---------+---------
    +-------+------+----------+-------+
     | 1 | SIMPLE | s1 | NULL | const | PRIMARY | PRIMARY | 4
    | const | 1 | 100.00 | NULL |
     +----+-------------+-------+------------+-------+---------------+---------+---------
    +-------+------+----------+-------+
     1 row in set, 1 warning (0.01 sec)
    
  6. eq_ref: 在连接查询时,如果被驱动表是通过主键或者唯一 二级索引列等值匹配的方式进行访问的(如果该主键或者 唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则对该被驱动表的访问方法就是 eq_ref

     mysql> EXPLAIN SELECT * FROM s1 INNER JOIN s2 ON s1.id = s2.id;
     +----+-------------+-------+------------+--------+---------------+---------+--------
    -+-----------------+------+----------+-------+
     | id | select_type | table | partitions | type | possible_keys | key | key_len
    | ref | rows | filtered | Extra |
     +----+-------------+-------+------------+--------+---------------+---------+--------
    -+-----------------+------+----------+-------+
     | 1 | SIMPLE | s1 | NULL | ALL | PRIMARY | NULL | NULL
    | NULL | 9688 | 100.00 | NULL |
     | 1 | SIMPLE | s2 | NULL | eq_ref | PRIMARY | PRIMARY | 4
    | xiaohaizi.s1.id | 1 | 100.00 | NULL |
     +----+-------------+-------+------------+--------+---------------+---------+--------
    -+-----------------+------+----------+-------+
     2 rows in set, 1 warning (0.01 sec)
    
  7. ref:当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是 ref

    mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
    +----+-------------+-------+------------+------+---------------+----------+---------+-----
    --+------+----------+-------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref
    | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+----------+---------+-----
    --+------+----------+-------+
    | 1 | SIMPLE | s1 | NULL | ref | idx_key1 | idx_key1 | 303 | cons
    t | 8 | 100.00 | NULL |
    +----+-------------+-------+------------+------+---------------+----------+---------+-----
    --+------+----------+-------+
    1 row in set, 1 warning (0.04 sec)
    
  8. fulltext: 全文索引

  9. ref_or_null: 当对普通二级索引进行等值匹配查询,该索引列的值也可以是 NULL 值时,那么对该表的访问方法就可能是 ref_or_null

     mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key1 IS NULL;
     +----+-------------+-------+------------+-------------+---------------+----------+--
    -------+-------+------+----------+-----------------------+
     | id | select_type | table | partitions | type | possible_keys | key | k
    ey_len | ref | rows | filtered | Extra |
     +----+-------------+-------+------------+-------------+---------------+----------+--
    -------+-------+------+----------+-----------------------+
     | 1 | SIMPLE | s1 | NULL | ref_or_null | idx_key1 | idx_key1 | 3
    03 | const | 9 | 100.00 | Using index condition |
     +----+-------------+-------+------------+-------------+---------------+----------+--
    -------+-------+------+----------+-----------------------+
     1 row in set, 1 warning (0.01 sec)
    
  10. index_merge: 一般情况下对于某个表的查询只能使用到一个索引,但我们唠叨单表访问方法时特意强调了在某些场景下可 以使用 Intersection 、 Union 、 Sort-Union 这三种索引合并的方式来执行查询

    mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a' OR key3 = 'a';
     +----+-------------+-------+------------+-------------+-------------------+---------
    ----------+---------+------+------+----------+----------------------------------------
    -----+
     | id | select_type | table | partitions | type | possible_keys | key
    | key_len | ref | rows | filtered | Extra |
     +----+-------------+-------+------------+-------------+-------------------+---------
    ----------+---------+------+------+----------+----------------------------------------
    -----+
     | 1 | SIMPLE | s1 | NULL | index_merge | idx_key1,idx_key3 | idx_key
    1,idx_key3 | 303,303 | NULL | 14 | 100.00 | Using union(idx_key1,idx_key3); Using
    where |
     +----+-------------+-------+------------+-------------+-------------------+---------
    ----------+---------+------+------+----------+----------------------------------------
    -----+
     1 row in set, 1 warning (0.01 sec)
    
  11. index: 当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是 index ,比如这样:

    mysql> EXPLAIN SELECT key_part2 FROM s1 WHERE key_part3 = 'a';
     +----+-------------+-------+------------+-------+---------------+--------------+----
    -----+------+------+----------+--------------------------+
     | id | select_type | table | partitions | type | possible_keys | key | key
    _len | ref | rows | filtered | Extra |
     +----+-------------+-------+------------+-------+---------------+--------------+----
    -----+------+------+----------+--------------------------+
     | 1 | SIMPLE | s1 | NULL | index | NULL | idx_key_part | 909
    | NULL | 9688 | 10.00 | Using where; Using index |
     +----+-------------+-------+------------+-------+---------------+--------------+----
    -----+------+------+----------+--------------------------+
     1 row in set, 1 warning (0.00 sec)
    

    上述查询中的搜索列表中只有 key_part2 一个列,而且搜索条件中也只有 key_part3 一个列,这两个列又恰 好包含在 idx_key_part 这个索引中,可是搜索条件 key_part3 不能直接使用该索引进行 ref 或者 range 方 式的访问,只能扫描整个 idx_key_part 索引的记录,所以查询计划的 type 列的值就是 index

  12. ALL: 全表扫描,唯一一个没有用到索引,需要特别关注

1.2.6 possible_keys和key

  1. possible_keys 列表示在某个查询语句中,对某个表执行单表查询时可能用到的索引有哪些
  2. key 列表示实际用到的索引有哪些
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 > 'z' AND key3 = 'a';
+----+-------------+-------+------------+------+-------------------+----------+---------+-
------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len |
ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+-------------------+----------+---------+-
------+------+----------+-------------+
| 1 | SIMPLE | s1 | NULL | ref | idx_key1,idx_key3 | idx_key3 | 303 |
const | 6 | 2.75 | Using where |
+----+-------------+-------+------------+------+-------------------+----------+---------+-
------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
  1. 上述执行计划的 possible_keys 列的值是 idx_key1,idx_key3 ,表示该查询可能使用到 idx_key1,idx_key3 两 个索引
  2. 然后 key 列的值是 idx_key3 ,表示经过查询优化器计算使用不同索引的成本后,最后决定使用 idx_key3 来执行查询比较划算
  3. 注意:possible_keys列中的值并不是越多越好,可能使用的索引越多,查询优化器计算查询成 本时就得花费更长时间,所以如果可以的话,尽量删除那些用不到的索引

1.2.7 key_len

  1. key_len 列表示当优化器决定使用某个索引执行查询时,该索引记录的最大长度,是由这三个部分构成的:
    1. 对于使用固定长度类型的索引列来说,它实际占用的存储空间的最大长度就是该固定值,对于指定字符集的 变长类型 的索引列来说,比如某个索引列的类型是 VARCHAR(100) ,使用的字符集是 utf8 ,那么该列实际占 用的最大存储空间就是 100 × 3 = 300 个字节
    2. 如果该索引列可以存储 NULL 值,则 key_len 比不可以存储 NULL 值时多1个字节
    3. 对于变长字段来说,都会有2个字节的空间来存储该变长列的实际长度
mysql> EXPLAIN SELECT * FROM s1 WHERE id = 5;
+----+-------------+-------+------------+-------+---------------+---------+---------+-----
--+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-----
--+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | const | PRIMARY | PRIMARY | 4 | cons
t | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+-----
--+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
  • 由于 id 列的类型是 INT ,并且不可以存储 NULL 值,所以在使用该列的索引时 key_len 大小就是 4
mysql> EXPLAIN SELECT * FROM s1 WHERE key2 = 5;
+----+-------------+-------+------------+-------+---------------+----------+---------+----
---+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+----------+---------+----
---+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | const | idx_key2 | idx_key2 | 5 | con
st | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+----------+---------+----
---+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
  • 可以看到 key_len 列就变成了 5 ,比使用 id 列的索引时多了 1
  • 对于可变长度的索引列来说,比如下边这个查询:
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | ref | idx_key1 | idx_key1 | 303 | cons
t | 8 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
  • 由于 key1 列的类型是 VARCHAR(100) ,所以该列实际最多占用的存储空间就是 300 字节
  • 又因为该列允许存储 NULL 值,所以 key_len 需要加 1
  • 又因为该列是可变长度列,所以 key_len 需要加 2
  • 所以最后 ken_len 的 值就是 303

1.2.8 ref

  1. 当使用索引列等值匹配的条件去执行查询时
  2. 也就是在访问方法是 const 、 eq_ref 、 ref 、 ref_or_null 、 unique_subquery 、 index_subquery 其中之一时, ref 列展示的就是与索引列作等值匹配的东东是个啥
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 = 'a';
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | ref | idx_key1 | idx_key1 | 303 | cons
t | 8 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+----------+---------+-----
--+------+----------+-------+
1 row in set, 1 warning (0.01 sec)

1.2.9 rows

  1. 如果查询优化器决定使用全表扫描的方式对某个表执行查询时,执行计划的 rows 列就代表预计需要扫描的行数
  2. 如果使用索引来执行查询时,执行计划的 rows 列就代表预计扫描的索引记录行数
mysql> EXPLAIN SELECT * FROM s1 WHERE key1 > 'z';
+----+-------------+-------+------------+-------+---------------+----------+---------+----
--+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref
| rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+----------+---------+----
--+------+----------+-----------------------+
| 1 | SIMPLE | s1 | NULL | range | idx_key1 | idx_key1 | 303 | NUL
L | 266 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+----------+---------+----
--+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

世纪晚霞

嘿嘿,末尾放上这几天广州的世纪晚霞,和大家一起分享下嘿嘿,祝好运连连
谢谢各位看到末尾的好朋友,谢谢你们 这么好看 还有眼光能够发现我吖,加油加油,冲!

4-1

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在 CentOS 7 上安装 Docker 并安装和部署 .NET Core 3.1

1. 安装 Docker 步骤 1.1&#xff1a;更新包索引并安装依赖包 先安装yum的扩展&#xff0c;yum-utils提供了一些额外的工具&#xff0c;这些工具可以执行比基本yum命令更复杂的任务 sudo yum install -y yum-utils sudo yum update -y #更新系统上已安装的所有软件包到最新…

视频分帧【截取图片】(YOLO目标检测【生成数据集】)

高效率制作数据集【按这个流程走&#xff0c;速度很顶】 本次制作&#xff0c;1059张图片【马路上流动车辆】 几乎就是全自动了&#xff0c;只要视频拍得好&#xff0c;YOLO辅助制作数据集就效率极高 视频中的图片抽取&#xff1a; 【由于视频内存过大&#xff0c;遇到报错执行…

2024导游资格考试,这些材料提前准备✅

2024年导游考试报名本月开始&#xff01; &#x1f499;大家提前准备好报名材料 1、个人近期白底1寸证件照。 2、身份证照片 3、学历照片 4、健康证明或健康承诺书 5、其他需要上传的材料 &#x1f499;照片文件不通过原因汇总&#xff0c;记得避开这些坑&#xff01; &#x1…

网络驱动移植(RTL8189)

1、把驱动放到内核文件夹中&#xff08;linux/drivers/net/wireless&#xff09;&#xff0c;对应的驱动可以在网上下载 2、修改该目录下的Kconfig和Makefile文件 3、配置内核&#xff08;make menuconfig&#xff09; 配置支持IEEE 802.11&#xff0c;选中8189模块&#xff0…

程序员 被辞退后如何赚钱

为啥现在大厂大量裁员&#xff1f;35以上的程序员为啥不被认可&#xff0c;很难找工作&#xff1f; 技术更新换代迅速&#xff1a; 技术领域发展极快&#xff0c;新的编程语言、框架和技术不断涌现。如果大龄程序员未能及时学习新技术和跟上行业变化&#xff0c;可能会被新一代…

SAP第二季度财报和进一步裁员计划

7月22日公布了截至 2024 年 6 月 30 日的第二季度财务报告。以下位总体指标 当前云计算在手订单达 148 亿欧元&#xff0c;按名义货币和固定汇率计算均增长 28%云收入增长 25%&#xff0c;其中云 ERP 套件收入增长 33%&#xff0c;均按名义货币和固定汇率计算总收入增长 10%&a…

【数据结构初阶】复杂度

目录 一、时间复杂度 1、时间复杂度的概念 2、大O的渐进表示法 3、常见的时间复杂度计算举例 二、空间复杂度 1、空间复杂度的概念 2、常见的空间复杂度计算举例 三、常见复杂度对比 正文开始—— 前言 一个算法&#xff0c;并非越简洁越好&#xff0c;那该如何衡量一个算法…

Mamba-yolo|结合Mamba注意力机制的视觉检测

一、本文介绍 PDF地址&#xff1a;https://arxiv.org/pdf/2405.16605v1 代码地址&#xff1a;GitHub - LeapLabTHU/MLLA: Official repository of MLLA Demystify Mamba in Vision: A Linear AttentionPerspective一文中引入Baseline Mamba&#xff0c;指明Mamba在处理各种高…

零基础入门:创建一个简单的Python爬虫管理系统

摘要&#xff1a; 本文将手把手教你&#xff0c;从零开始构建一个简易的Python爬虫管理系统&#xff0c;无需编程基础&#xff0c;轻松掌握数据抓取技巧。通过实战演练&#xff0c;你将学会设置项目、编写基本爬虫代码、管理爬取任务与数据&#xff0c;为个人研究或企业需求奠…

回溯题目的套路总结

前言 昨天写完了LeeCode的7&#xff0c;8道回溯算法的题目&#xff0c;写一下总结&#xff0c;这类题目的共同特点就是暴力搜索问题&#xff0c;排列组合或者递归&#xff0c;枚举出所有可能的答案&#xff0c;思路很简单&#xff0c;实现起来的套路也很通用&#xff0c;一…

poi库简单使用(java如何实现动态替换模板Word内容)

目录 Blue留言&#xff1a; Blue的推荐&#xff1a; 什么是poi库&#xff1f; 实现动态替换 第一步&#xff1a;依赖 第二步&#xff1a;实现word模板中替换文字 模板word&#xff1a; 通过以下代码&#xff1a;&#xff08;自己建一个类&#xff0c;随意取名&#xf…

SpringBoot框架学习笔记(五):静态资源访问、Rest风格请求处理、配置视图解析器、接收参数的相关注解详解

1 WEB开发-静态资源访问 1.1 基本介绍 &#xff08;1&#xff09;只要静态资源放在类路径的以下目录&#xff1a;/static、/public、/resources、/META-INF/resources 可以被直接访问。maven项目的类路径即为main/resources目录--对应SpringBoot源码为WebProperties.java类 …

nginx如何开启优先访问压缩文件

nginx输出gzip有很多条件&#xff1a; 开启了gzip&#xff1a;gzip on;gzip_types定义了content-type&#xff0c;需要注意的是text/html是强制性的&#xff0c;不需要也不能再添加这个响应输出的content-type在gzip_types里输出的content-length大于等于nginx配置的gzip_min_…

【TypeScript 一点点教程】

文章目录 一、开发环境搭建二、基本类型2.1 类型声明2.2 基本类型 三、编译3.1 tsc命令3.2 tsconfig.json3.2.1 基本配置项includeexcludeextendsfiles 3.2.2 compilerOptions编译器的配置项 四、面向对象4.1 类4.2 继承4.3 抽象类4.4 接口 一、开发环境搭建 下载Node.js《Nod…

操作系统——进程与线程(死锁)

1&#xff09;为什么会产生死锁&#xff1f;产生死锁有什么条件&#xff1f; 2&#xff09;有什么办法解决死锁&#xff1f; 一、死锁 死锁:多个程序因竞争资源而造成的一种僵局&#xff08;互相等待对方手里的资源&#xff09;&#xff0c;使得各个进程都被阻塞&#xff0c;…

02.C++入门基础(下)

1.函数重载 C支持在同一作用域中出现同名函数&#xff0c;但是要求这些同名函数的形参不同&#xff0c;可以是参数个数不同或者类型不同。这样C函数调用就表现出了多态行为&#xff0c;使用更灵活。C语言是不支持同一作用域中出现同名函数的。 1、参数类型不同 2、参数个数不同…

volatile,最轻量的同步机制

目录 一、volatile 二、如何使用&#xff1f; 三、volatile关键字能代替synchronized关键字吗&#xff1f; 四、总结&#xff1a; 还是老样子&#xff0c;先来看一段代码&#xff1a; 我们先由我们自己的常规思路分析一下代码&#xff1a;子线程中&#xff0c;一直循环&…

DocRED数据集

DocRED数据集文件夹包含多个JSON文件&#xff0c;每个文件都有不同的用途。以下是这些文件的用途解释以及哪个文件是训练集&#xff1a; 文件解释 dev.json&#xff1a;包含开发集&#xff08;验证集&#xff09;的数据&#xff0c;通常用于模型调优和选择超参数。 label_map…

java面向对象进阶进阶篇--《包和final》

一、前言 今天还是面向对象相关知识点的分享&#xff0c;包是写小型项目时不可或缺的存在&#xff0c;final关键字用的地方不算太多。idea会提示我们导包&#xff0c;有时会自动导包&#xff0c;确实十分方便。但是我们也不能不会自己去导包。 面向对象篇不出意外的话本周就要…

【线性代数】矩阵变换

一些特殊的矩阵 一&#xff0c;对角矩阵 1&#xff0c;什么是对角矩阵 表示将矩阵进行伸缩&#xff08;反射&#xff09;变换&#xff0c;仅沿坐标轴方向伸缩&#xff08;反射&#xff09;变换。 2&#xff0c;对角矩阵可分解为多个F1矩阵&#xff0c;如下&#xff1a; 二&a…