Mysql学习笔记-进阶篇

news2025/1/11 20:53:36

一、存储引擎

1、MYSQL体系结构

连接层、服务层、引擎层、存储层;

2、存储引擎简介

存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是库的,所以存储引擎也可被称为表类型。

1)在创建表时指定存储引擎

CREATE TABLE 表名(
    字段1名 字段1类型 [COMMENT 字段1注释],
    ……
    字段n名 字段n类型 [COMMENT 字段n注释]
)ENGINE=INNODB [COMMENT 表注释]

2)查看数据库引擎

--查看数据库的引擎

mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| ndbcluster         | NO      | Clustered, fault-tolerant tables                               | NULL         | NULL | NULL       |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| ndbinfo            | NO      | MySQL Cluster system information storage engine                | NULL         | NULL | NULL       |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
11 rows in set (0.04 sec)
--查看数据库中某个表使用的什么存储引擎

show create table xxx;

3、存储引擎特点

(一)INNODB

        1)介绍:

InnoDB是一种兼顾高可靠性和高性能的通用存储引擎,在Mysql 5.5之后,InnoDB是mysql默认的存储引擎

        2)特点:

DML操作遵循ACID模型,支持事务;

行级锁,支持并发访问性能;

支持外键FOREIGN KEY约束,保证数据完整性和正确性;

        3)文件:

xxx.ibd  :xxx是文件名,InnoDB引擎的每张表都对应这样一个表空间文件,存储该表的表结构(frm、sdi)、数据和索引

参数:innodb_file_per_table

        使用命令可查看idb文件中的文件结构

        ibd2sdi xxx.ibd

-- 查看变量,每个表一个文件,8.0版本之后默认是ON
mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.01 sec)
        4)逻辑存储结构

表空间:TableSpace

段:Segment

区:Extent     默认大小  1M   包含64个页

页:Page      默认大小   16K

行:Row

        (二)MyISAM

        1)介绍:

MyISAM是MYSQL早期默认存储引擎。

        2)特点:

不支持事务,不支持外键;

支持表锁,不支持行锁;

访问速度快;

        3)  文件:

xxx.sdi:存储表结构信息

xxx.MYD:存储数据

xxx.MYI:存储索引

(三)Memory

       1)介绍:

Memory存储引擎的表数据是存储在内存中的,受到断电问题、或硬件问题的影响,只能将这些表作为临时表或者缓存使用。

        2)特点:

内存存放

Hash索引(默认)

        3)文件:

xxx.sdi:存放表结构信息

4、存储引擎选择

根据应用系统特点选择存储引擎,对于复杂应用,可以根据实际情况,选择多种存储引擎的组合。

InnoDB:mysql默认存储引擎,支持事务和外键。如果应用对事务的完整性有较高要求,在并发条件下要求数据一致性,数据操作除了插入和查询之外,还有很多更新和删除操作,那么innoDB存储引擎是比较合适的选择。

MyISAM:如果数据以插入和查询为主,对数据的更新和删除较少,并且对事务的完整性和并发性要求不高,选择这个存储引擎比较合适。

Memory:将所有数据保存到内存中,访问速度快,通常用于临时表及缓存。memory对表的大小有限制,太大的表无法缓存到内存中,而且无法保证数据的安全性。

二、索引

1、索引概述

介绍:

索引是帮助mysql高效获取数据的一种数据结构有序的)。在数据之外,数据库还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

优缺点:

优势劣势
提高数据检索效率,降低数据库的IO成本索引也是要暂用存储空间的
通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗索引大大提高了查询效率,同时降低了更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率降低。

2、索引结构

索引结构描述
B+Tree索引最常见的索引类型,大部分存储引擎都支持B+树索引
Hash索引底层数据结构使用hash表实现的,只有精确匹配索引列的查询才有效,不支持范围查询
R-Tree(空间索引)空间索引是MyISAM引擎的一种特殊索引类型,主要用于地理空间数据类型,用的较少
Full-text(全文索引)是一种通过建立倒排索引,快速匹配文档的方式。类似于Lucene、Solr、ES

索引支持情况

索引InnoDBMyISAMMemory
B+Tree索引你支持支持支持
Hash索引不支持不支持支持
R-Tree索引不支持支持不支持
Full-text全文索引5.6版本之后支持支持不支持

我们平时说的索引结构,如果不做特殊说明都是指B+Tree索引。

1)二叉树

左小右大的二叉树

缺点:

1)顺序插入时,会形成一个链表查询性能大大降低

2)大数据量情况下,层级较深,检索速度慢。

2)红黑树

使用红黑树,解决二叉树的平衡问题(第一个问题),但是问题二依然存在

大数据量情况下,层级较深,检索速度慢。

3)B树(多路平衡查找树)

以一颗最大度数(max-degree)为5(5阶)的B-Tree为例(每个节点最多存储4个key,5个指针)

树的度数:指的是一个节点的最大子节点个数。

4)B+树

相对于B-Tree特点:

1)所有数据都出现在叶子节点,非叶子节点只起到索引作用

2)叶子节点是个单向链表

以一个最大度数为4(4阶)的B+树为例

Mysql索引数据结构对经典的B+Tree进行了优化,在原B+Tree的基础上,增加了一个指向相邻叶子节点的链表指针,就形成了一个带有顺序指针的B+Tree,提高了区间访问的性能。

5)Hash

哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在哈希表中。

如果两个或者多个键值,映射到一个相同的槽位上,他们就产生了哈希冲突(也成为哈希碰撞),可以通过链表来解决。

hash索引特点

1)只能用于对等比较(=,in),不支持范围查询

2)无法利用索引完成排序操作

3)查询效率高,通常只需要一次检索就可以了,效率通常要高于B+Tree索引

存储引擎支持

在mysql中,支持hash索引的是memory引擎,而InnoDB中具有自适应hash功能,hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的。

6)为什么InnoDB采用B+Tree索引结构

1)相对于二叉树层级更少,搜索效率更高。

2)对于B-树,无论是叶子结点还是非叶子节点,都会保存数据,这样导致一页存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加数的高度,导致性能下降。

3)对于Hash索引,B+Tree支持范围查找及排序操作。

3、索引分类

分类含义特点关键字
主键索引针对于表中主键创建的索引默认自动创建,只能有一个primary
唯一索引避免表中某个列的值数据重复可以有多个unique
普通索引快速定位特定数据可以有多个
全文索引全文索引查找的是文本中的关键词,而不是比较索引中的值可以有多个fulltext

在InnoDB存储引擎中,根据索引的存储形式又可以分为以下两种

分类含义特点
聚集索引(Clustered Index)将数据存储于索引结构放到一块,索引结构的叶子节点保存了行数据必须有,而且只有一个
二级索引(Secondary Index)将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键可以存在多个

聚集索引选取规则

1)如果存在主键,主键索引就是聚集索引

2)如果没有主键,将使用第一个唯一索引(UNIQUE)作为聚集索引

3)如果表没有主键或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引

思考:

InnoDB主键索引的B+Tree高度为多高?

假设:

一行数据大小为1k,一页中可以存储16行这样的数据,InnoDB的指针暂用6个字节的空间,主键即使是BigInt,暂用字节数为8

高度为2:

n*8+(n+1)*6 =16*1024      算出n约为1170

1171*16=18736

高度为3:

1171*1171*16=2193,9856 ≈ 2200万

4、索引语法

--创建索引
CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name(index_col_name……);
--查看索引
SHOW INDEX FROM table_name;
--删除索引
DROP INDEX index_name ON table_name

5、sql性能分析

(一)SQL执行频率

Msql客户端连接成功后,通过命令show 【session|global】status 可以提供服务器状态信息,通过如下指令可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT访问频次。如果没有select查询或者很少的查询操作,就没必要做优化。

show global status like 'Com_______'              7个下划线

--查看各种语句使用频率
mysql> show global status like 'Com_______'
    -> ;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 4     |
| Com_delete    | 0     |
| Com_import    | 0     |
| Com_insert    | 8     |
| Com_repair    | 0     |
| Com_revoke    | 2     |
| Com_select    | 263   |
| Com_signal    | 0     |
| Com_update    | 10    |
| Com_xa_end    | 0     |
+---------------+-------+
11 rows in set (0.01 sec)

(二)慢查询日志

1)查看慢查询日志是否开启

show ariables like ‘slow_query_log’

--查看慢查询日志开关是否开启,默认是关闭
mysql> show variables like 'slow_query_log';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| slow_query_log | OFF   |
+----------------+-------+
1 row in set (0.02 sec)

慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有sql语句日志。

2)开启慢查询

mysql的慢查询日志默认没有开启,需要在MYSQL配置文件(/etc/my.cnf)中配置如下信息:

--开启mysql慢查询日志开关
slow_query_log=1
--设置慢日志的时间为2秒,sql语句执行时间超过两秒,就会视为慢查询,记录慢查询日志
long_query_time=2
3)查看慢查询

配置完毕后,通过以下指令,重启mysql服务器进行测试,查看慢日志记录文件中记录的信息/var/lib/mysql/localhost-slow.log

(三)profile详情

show profiles命令在做sql优化时,能够帮我们了解每一条sql时间都耗费到哪里去了。通过have_profiling参数,能够看到当前mysql是否支持profile操作:

1)是否支持profile操作

select @@have_profiling;

默认profiling是关闭的,

2) 查看profiling是否开启

select @@profiling;

3)开启profile

可以在session|global级别开启profiling

set profiling=1;

--当前mysql是否支持profile操作
mysql> select @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES              |
+------------------+
1 row in set, 1 warning (0.00 sec)

--查看profiling开关是否开启,默认是关闭状态。 1表示开启,0表示关闭。
mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> show profiles;
Empty set, 1 warning (0.00 sec)


--打开profile详情

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
|           1 |
+-------------+
1 row in set, 1 warning (0.01 sec)
4)查看每一条sql语句耗时情况

开启profiling开关之后,通过如下指令,查看指令的执行耗时。

show profiles;

5)查看每个极端耗时情况

--查看指定query_id的查询语句每个阶段的耗时情况

show profile query for query_id;

6)查看每个阶段CPU使用情况

--查看指定query_id的sql语句cpu使用情况;

show profile cpu query for query_id;

7)下面是使用示例
--查看每一条sql耗时基本情况
show profiles;
--查看指定query_id的查询语句每个阶段的耗时情况
show profile query for query_id;

--查看指定query_id的SQL语句CPU的使用情况
show profile cpu for query query_id;

--执行一些sql语句,供后面查询用
mysql> select * from account;
+----+--------+-------+
| id | name   | money |
+----+--------+-------+
|  1 | 张三   |  2000 |
|  2 | 李四   |  2000 |
+----+--------+-------+
2 rows in set (0.00 sec)

mysql> select * from t01;
Empty set (0.00 sec)

mysql> select * from user;
+----+--------+----------+
| id | name   | password |
+----+--------+----------+
|  1 | 张三   | 123      |
|  2 | 李四   | 123      |
|  3 | 王五   | 123      |
|  4 | 王五   | 123      |
|  5 | NULL   | 123456   |
|  6 | doumi  | 123456   |
+----+--------+----------+
6 rows in set (0.00 sec)

mysql> select * from user where id=3
    -> ;
+----+--------+----------+
| id | name   | password |
+----+--------+----------+
|  3 | 王五   | 123      |
+----+--------+----------+
1 row in set (0.00 sec)

mysql> select * from user where name='doumi';
+----+-------+----------+
| id | name  | password |
+----+-------+----------+
|  6 | doumi | 123456   |
+----+-------+----------+
1 row in set (0.00 sec)
--查看每一条SQL的耗时情况

查看每条sql语句执行耗时情况

show profiles;

mysql> show profiles;
+----------+------------+---------------------------------------+
| Query_ID | Duration   | Query                                 |
+----------+------------+---------------------------------------+
|        1 | 0.01071200 | show tables                           |
|        2 | 0.00215000 | select * from account                 |
|        3 | 0.00290200 | select * from t01                     |
|        4 | 0.00397000 | select * from user                    |
|        5 | 0.00320600 | select * from user where id=3         |
|        6 | 0.00151600 | select * from user where name='doumi' |
+----------+------------+---------------------------------------+
6 rows in set, 1 warning (0.00 sec)

show profile for query 6;    -- 6是上面show profiles命令结果中的query_id

--查看query_id 为6的那条sql语句每个阶段的耗时情况
mysql> show profile for query 6;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000087 |
| Executing hook on transaction  | 0.000009 |
| starting                       | 0.000008 |
| checking permissions           | 0.000007 |
| Opening tables                 | 0.000045 |
| init                           | 0.000008 |
| System lock                    | 0.000009 |
| optimizing                     | 0.000943 |
| statistics                     | 0.000060 |
| preparing                      | 0.000111 |
| executing                      | 0.000102 |
| end                            | 0.000007 |
| query end                      | 0.000005 |
| waiting for handler commit     | 0.000012 |
| closing tables                 | 0.000011 |
| freeing items                  | 0.000034 |
| cleaning up                    | 0.000058 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.01 sec)

show profile cpu for query 6;    -- 6是上面show profiles命令结果中的query_id

--查看query_id为6的那条sql语句CPU消耗情况
mysql> show profile cpu for query 6;
+--------------------------------+----------+----------+------------+
| Status                         | Duration | CPU_user | CPU_system |
+--------------------------------+----------+----------+------------+
| starting                       | 0.000087 | 0.000073 |   0.000013 |
| Executing hook on transaction  | 0.000009 | 0.000003 |   0.000007 |
| starting                       | 0.000008 | 0.000006 |   0.000002 |
| checking permissions           | 0.000007 | 0.000004 |   0.000003 |
| Opening tables                 | 0.000045 | 0.000043 |   0.000002 |
| init                           | 0.000008 | 0.000003 |   0.000005 |
| System lock                    | 0.000009 | 0.000007 |   0.000002 |
| optimizing                     | 0.000943 | 0.000023 |   0.000175 |
| statistics                     | 0.000060 | 0.000043 |   0.000016 |
| preparing                      | 0.000111 | 0.000043 |   0.000068 |
| executing                      | 0.000102 | 0.000096 |   0.000006 |
| end                            | 0.000007 | 0.000003 |   0.000004 |
| query end                      | 0.000005 | 0.000003 |   0.000003 |
| waiting for handler commit     | 0.000012 | 0.000010 |   0.000002 |
| closing tables                 | 0.000011 | 0.000009 |   0.000002 |
| freeing items                  | 0.000034 | 0.000010 |   0.000024 |
| cleaning up                    | 0.000058 | 0.000022 |   0.000035 |
+--------------------------------+----------+----------+------------+
17 rows in set, 1 warning (0.01 sec)

(四)explain执行计划

EXPLAIN或者DESC命令获取mysql如何执行select语句的信息,包括在select执行过程中,表如何连接及连接的顺序。

语法:

直接在select 语句前面加上explain/desc

EXPLAIN SELECT 字段名 FROM 表名 WHERE 条件;

DESC SELECT 字段名 FROM 表名 WHERE 条件;

mysql> explain select * from user where id=2;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)

mysql> desc select * from user where id=2;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

执行计划中每个字段含义

id:select查询的序列号,表示查询中执行select子句或者操作表的顺序(id相同,执行顺序从上到下,id不同,值越大越先执行)

select_type:表示查询类型,常见的有SIMPLE(简单表,即不使用表连接或子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的语句)、SUBQUERY(select或者where之后包含了子查询)

type:表示连接类型,性能由好到差的连接类型是:NULL,system、const、eq_ref、ref、range、index、all

possible_keys:显示可能应用在这张表的上索引,一个或多个。

key:实际用到的索引,如果没用到展示位null

key_lens:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好。

rows:mysql认为必须要执行查询的行数,在InnoDB引擎的表中,是一个估计值,可能并不总是准确的。

filtered:表示返回结果的行数占需读取行数的百分比,filtered的值越大越好。

mysql> select s.*,c.* from student_course sc,student s,course c where sc.student_id =s.id and sc.course_id = c.id;
+----+-----------+------------+----+--------+
| id | name      | no         | id | name   |
+----+-----------+------------+----+--------+
|  1 | 红小豆    | 2000100101 |  1 | JAVA   |
|  1 | 红小豆    | 2000100101 |  2 | PHP    |
|  1 | 红小豆    | 2000100101 |  3 | MYSQL  |
|  2 | 张天爱    | 2000100102 |  3 | MYSQL  |
|  2 | 张天爱    | 2000100102 |  3 | MYSQL  |
|  3 | 鹿晗      | 2000100103 |  4 | HADOOP |
+----+-----------+------------+----+--------+
6 rows in set (0.00 sec)

mysql> 
mysql> 
mysql> desc select s.*,c.* from student_course sc,student s,course c where sc.student_id =s.id and sc.course_id = c.id;;
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref                   | rows | filtered | Extra                                      |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------------------------+
|  1 | SIMPLE      | s     | NULL       | ALL    | PRIMARY       | NULL    | NULL    | NULL                  |    4 |   100.00 | NULL                                       |
|  1 | SIMPLE      | sc    | NULL       | ALL    | NULL          | NULL    | NULL    | NULL                  |    6 |    16.67 | Using where; Using join buffer (hash join) |
|  1 | SIMPLE      | c     | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | lyltest1.sc.course_id |    1 |   100.00 | NULL                                       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------------------------+
3 rows in set, 1 warning (0.00 sec)

mysql> explain
    -> select s.* from student s where 
    -> s.id in(select sc.student_id from student_course sc where sc.course_id=
    -> (select c.id from course c where c.name='MYSQL'));
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                                     |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------------+
|  1 | PRIMARY     | s     | NULL       | ALL  | PRIMARY       | NULL | NULL    | NULL |    4 |   100.00 | NULL                                                      |
|  1 | PRIMARY     | sc    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    6 |    16.67 | Using where; FirstMatch(s); Using join buffer (hash join) |
|  3 | SUBQUERY    | c     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |    25.00 | Using where                                               |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------------+
3 rows in set, 1 warning (0.01 sec)

需要重点关注的字段

6、索引使用

使用原则

最左前缀法则

如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从最左列开始,并且不跳过索引中的列。

如果跳过某个列,索引将部分失效(后面的字段索引失效)

下图说明:跟查询条件的位置没关系,只要查询中包含了索引字段就行,包含了三个字段,则使用三个列的索引

索引失效的情况:
1)范围查询

联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效。使用>=,<=替代>,< ,使所有索引字段都生效。

explain select * from tb_user where profession=‘软件工程’ and age>30 and status='0';

--索引idx_user_pro_age_sta只能使用profession

explain select * from tb_user where profession=‘软件工程’ and age>=30 and status='0';

--索引idx_user_pro_age_sta 所有索引字段都生效

2)索引列运算

不要在索引列上进行运算操作,索引将失效。

3)字符串不加引号

4)模糊查询

如果仅仅是尾部进行模糊匹配,索引不会失效,如果是头部模糊匹配,索引失效。

应尽量避免模糊查询,开头加%的情况。

5)or连接的条件

用or分割开的条件,如果or前的条件中的列有索引,or后面的条件中的列没索引,那么涉及的索引都不会被引用到。

需要使or中的所有条件都有索引,查询才能走索引。

6)数据分布影响

如果mysql评估,使用索引比全表扫描更慢,则不使用索引。

数据的分布,可能会影响使用索引还是不使用。例如,某个字段如果大部分都是null ,则条件is null 就不走索引,is not null就会总索引

使用规则-SQL提示

sql提示是优化数据库的一个重要手段,简单来说就是,在sql语句中加入一些认为的提示,来达到优化操作的目的。

use index

explain select * from tb_user use index(idx_user_pro) where profession='软件工程';

ignore index

explain select * from tb_user use ignore index(idx_user_pro) where profession='软件工程';

force index

explain select * from tb_user use force index(idx_user_pro) where profession='软件工程';

使用规则-覆盖索引

尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到),减少select *。

知识小贴士:

using index condition:查询使用了索引,但是需要回表查询数据。

using where using index:查询使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据

前缀索引
1》使用场景:

当字段类型为字符串(varchar、text)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费很多磁盘IO,影响查询效率。此时可以只将字符串的一部分建立索引,这样可以大大节约索引空间,从而提高索引效率

2》语法:

create index idx_xxx on table_name(column(n))          --n表示字符串的前多少个字符

3》前缀长度:

可以根据索引的选择性来决定,而选择性是指,不重复的索引值(基数)和表中记录总数的比值,索引选择性越高,则查询效率越高。唯一索引的选择性是1,这是最好的索引选择性,效率也是最好的。

select count(distinct email)/count(*) from tb_user;

select count( distinct substring(email,1,5)) /count(*) from tb_user;

执行结果如下图:

4》查询流程

根据前5个字符,找到对应数据的id,根据id回表,找到对应行,再把表中数据跟条件对比;

循环找到下一个辅助索引中对应的id,回表……

如下图:

单列索引&联合索引选择

单列索引:一个索引只包含一个列。

联合索引:一个索引包含多个列。

在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引而非单列索引

单列索引情况:

explain select id,phone,name from tb_user where phone=‘12345678912’ and name=‘小美’

多条件联合查询时,mysql优化器会评估哪个索引的效率更高,会使用该索引完成本次查询。

联合索引情况:

如果查询覆盖索引,可以避免回表。

7、索引设计原则

三、sql优化

四、视图/存储过程/触发器

五、锁

六、InnoDB引擎

七、Mysql管理

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

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

相关文章

天阳科技集团北京卡洛其项目管理专家李先林受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 天阳科技集团北京卡洛其项目管理专家李先林先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“应用软件项目管理标准化实践探讨”。大会将于6月29-30日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1…

.net 调用海康SDK的常用操作封装

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不仅…

(南京观海微电子)——TFT激光修复技术

激光在显示面板修复方面的应用 液晶面板包括TFT玻璃、CF玻璃、面板以及后段模块组装等一系列工艺制作过程。每段过程中都会产生一定的缺陷&#xff0c;例如亮点、暗点、闪点、碎亮点等。这些缺陷会导致部分区域显示不良&#xff0c;但是我们可以通过暗点化、亮点化、ITO隔离、…

【Linux】pycharmgit相关操作

目录 1. git安装配置2. 相关内容3. pycharm连接远程仓库3.1 配置3.2 clone远程仓库3.3 本地仓库上传远程 4. 分支管理4.1 更新代码4.2 新建分支4.3 分支合并4.4 代码比对 5. 版本管理6. 命令行操作6.1 配置git6.2 基础操作6.3 分支操作 1. git安装配置 下载链接&#xff1a;官…

多模态大模型:基础架构

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

如何进行文件映射

创建一个文件WebMvcConfig package com.itheima.config;import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.…

Retrofit 注解参数详解

添加依赖 implementation com.squareup.retrofit2:retrofit:2.9.0 implementation com.squareup.retrofit2:converter-gson:2.9.0 初始化Retrofit val retrofit Retrofit.Builder().baseUrl("http://api.github.com/").addConverterFactory(GsonConverterFactory…

深度遍历-求矩阵最长递增路径

一、问题描述 二、解题思路 和深度遍历-求岛屿数量的思路一致&#xff0c;不过这里不需要设置判断是否产生访问过的boolean二维数组了&#xff0c;因为在这个题目里面是求递增序列&#xff0c;下一个元素只有比当前元素大才会往前走&#xff0c;即使在回头检查时&#xff0c;发…

大模型网信办备案全网最详细流程【附附件】

本文要点&#xff1a;大模型备案最详细说明&#xff0c;大模型备案条件有哪些&#xff0c;《算法安全自评估报告》模板&#xff0c;大模型算法备案&#xff0c;大模型上线备案&#xff0c;生成式人工智能(大语言模型)安全评估要点&#xff0c;网信办大模型备案。 大模型备案安…

Spring学习笔记(九)简单的SSM框架整合

实验目的 掌握SSM框架整合。 实验环境 硬件&#xff1a;PC机 操作系统&#xff1a;Windows 开发工具&#xff1a;idea 实验内容 整合SSM框架。 实验步骤 搭建SSM环境&#xff1a;构建web项目&#xff0c;导入需要的jar包&#xff0c;通过单元测试测试各层框架搭建的正确…

SpringBootWeb 篇-入门了解 Spring Cache 、Spring Task 与 WebSocket 框架

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Spring Cache 概述 1.1 Spring Cache 具体使用 1.1.1 引入依赖 1.1.2 Spring Cache 相关注解的介绍 2.0 Spring Task 概述 2.1 cron 表达式 2.2 Spring Task 使用…

平安:PostgreSQL开发运维案例

PostgreSQL作为功能强大且开源的关系型数据库管理系统&#xff0c;广泛应用于各种开发和运维场景中。本文将探讨PostgreSQL在开发和运维中的最佳实践&#xff0c;涵盖环境搭建、性能优化、安全管理和备份恢复等关键环节&#xff0c;旨在帮助读者充分发挥PostgreSQL的优势&#…

MFC工控项目实例之四在调试目录下创建指定文件夹

承接专栏《MFC工控项目实例之三theApp变量传递对话框参数》 在调试目录Debug下创建DATA、LIB、TEMP三个文件夹 1、SEAL_PRESSURE.h中添加代码 class CSeatApp : public CWinApp { ... public:CString m_Path;CString m_DataPath,m_TempPath,m_LibPath; ... };2、SEAL_PRESSURE…

机器人、人工智能相关领域 news/events (专栏目录)

Some Insights 一些机器人、人工智能或相关领域的news、events等 1. 智能制造 - 你需要了解的 10 个基本要素 2. 现实世界中的人工智能&#xff1a;工业制造的 4 个成功案例研究 3. 企业使用人工智能情况调查 4. 未来工厂中的人工智能&#xff1a;人工智能加速制造成果规模…

[C++ STL] vector 详解

标题&#xff1a;[C STL] vector 详解 水墨不写bug 目录 一、背景 二、vector简介 三、vector的接口介绍 &#xff08;1&#xff09;默认成员函数接口 i&#xff0c;构造函数&#xff08;constructor&#xff09; ii&#xff0c;析构函数&#xff08;destructor&#xff0…

Matlab|基于手肘法的kmeans聚类数的精确识别【K-means聚类】

主要内容 在电力系统调度研究过程中&#xff0c;由于全年涉及的风、光和负荷曲线较多&#xff0c;为了分析出典型场景&#xff0c;很多时候就用到聚类算法&#xff0c;而K-means聚类就是常用到聚类算法&#xff0c;但是对于K-means聚类算法&#xff0c;需要自行指定分类数&…

【深度学习】TCN,An Empirical Evaluation of Generic Convolutional【二】

文章目录 膨胀卷积什么是膨胀卷积膨胀卷积公式PyTorch代码 从零开始手动实现一个1D膨胀卷积&#xff0c;不使用PyTorch的nn.Conv1d1. 基本概念2. 手动实现1D膨胀卷积 TCN结构如何使用TCN源码说明1. Chomp1d 类2. TemporalBlock 类3. TemporalConvNet 类 使用方法 膨胀卷积 什么…

Unity 3D 物体的Inspector面板

1、Transform&#xff1a;位置、旋转、大小 2、Mesh Filter&#xff1a;物体的形状 3、Mesh Renderer&#xff1a;物体渲染&#xff08;物体的衣服&#xff09; 4、Collider&#xff1a;碰撞体

python错题(1)

字典中min&#xff0c;max最后比较的是键&#xff0c;输出的是键