赞
踩
查看已有数据库:
show databases;
创建数据库:
create database 数据库名字 default charset utf8 collate utf8_general_ci;
删除数据库:
drop database 数据库名字;
进入数据库(进入文件夹)
use 数据库名字;
查看文件夹下所有的数据表(文件):
show tables;
创建表:
create table user(
user_id int not null primary keyauto_increment,
username varchar(16) not null,
password char(8) not null,
sexy char(4) not null
)default charset=utf8;
查看表详细信息:desc 表名称;
查看表:select * from 表名称;
删除表:
drop table 表名称;
插入数据:
insert into 表名(字段名1,字段名2) values (1000,18);
insert into 表名(字段名1,字段名2) values (1000,18),(133,55);
整型:
tinyint:
有符号,取值范围-128~127【默认】
无符号,0~255【 tinyint unsigned】
int:
有符号:-2147483648~2147483647
无符号:…
bigint
小数:
float
double
decimal:
准确的小数值,m是数字总个数(负号不算),d是小数点后个数,m最大值65,d最大30
如:
create table 表名称{
salary decimal(8,2) 不超过8个数字,小数点后2个
}default charset=utf8;
字符串:
char(m):查询速度快 m最大255个字符
定长字符串:char(11) 固定11个字符串进行存储,哪怕没有11个,也会存储11个
varchar(m):节省空间 m最大是65535字节
变长字符串:varchar(11)
text(m): m最大 65535个字符
mediumtext
longtext
时间:
datetime:
YYYY-MM-DD HH:MM:SS
date:
YYYY-MM-DD
新增数据:
insert into 表名(字段名1,字段名2) values (值1,值2),(值1,值2);
删除数据:
delete from 表名;
delete from 表名 where 条件;id in(1,3)等于id=1 or id=3;
修改数据:
update 表名 set 列=值,列=值 where 条件;
查询数据:
select * from 表名称;
select 字段名,字段名 from 表名称 where 条件;
有主键,具有原子性,字段不可分割
表的每个字段都必须与主键具有直接关系,而非间接关系
表中的字段与主键不能有传递依赖,必须是直接依赖,不满足第三范式会出现大量的数据冗余
这才是完整的SELECT查询
SELECT DISTINCT column, AGG_FUNC(column_or_expression), …
FROM mytable
JOIN another_table
ON mytable.column = another_table.column
WHERE constraint_expression
GROUP BY column
HAVING constraint_expression
ORDER BY column ASC/DESC
LIMIT count OFFSET COUNT;
1. FROM 和 JOINs
FROM 或 JOIN会第一个执行,确定一个整体的数据范围. 如果要JOIN不同表,可能会生成一个临时Table来用于 下面的过程。总之第一步可以简单理解为确定一个数据源表(含临时表)
2. WHERE
我们确定了数据来源 WHERE 语句就将在这个数据源中按要求进行数据筛选,并丢弃不符合要求的数据行,所有的筛选col属性 只能来自FROM圈定的表. AS别名还不能在这个阶段使用,因为可能别名是一个还没执行的表达式
3. GROUP BY
如果你用了 GROUP BY 分组,那GROUP BY 将对之前的数据进行分组,统计等,并将是结果集缩小为分组数.这意味着 其他的数据在分组后丢弃.
4. HAVING
如果你用了 GROUP BY 分组, HAVING 会在分组完成后对结果集再次筛选。AS别名也不能在这个阶段使用.
5. SELECT
确定结果之后,SELECT用来对结果col简单筛选或计算,决定输出什么数据.
6. DISTINCT
如果数据行有重复DISTINCT 将负责排重.
7. ORDER BY
在结果集确定的情况下,ORDER BY 对结果做排序。因为SELECT中的表达式已经执行完了。此时可以用AS别名.
LIMIT / OFFSET
最后 LIMIT 和 OFFSET 从排序的结果中截取部分数据.
distinct
DISTINCT 查询不重复的内容
select distinct 字段 from 表;
FULL JOIN、LEFT JOIN、RIGHT JOIN
- FULL JOIN:将两个表数据1-1连接,保留A或B的原有行,如果某一行在另一个表不存在,会用 NULL来填充结果数据。
- LEFT OUTER JOIN, RIGHT OUTER JOIN, 或 FULL OUTER JOIN, 和 LEFT JOIN, RIGHT JOIN, and FULL JOIN 等价.
- 所有在用这三个JOIN时,你需要单独处理 NULL.你计算一些行的平均值的时候,如果是0会参与计算导致平均值差错,是NULL则不会参与计算。可以用IS NULL和 IS NOT NULL 来选在某个字段是否等于 NULL.
AS 和 表达式筛选
AS不仅用在表达式别名上,普通的属性列甚至是表(table)都可以取一个别名
1. as
SELECT column AS better_column_name, …
FROM a_long_widgets_table_name AS mywidgets
INNER JOIN widget_sales
ON mywidgets.id = widget_sales.widget_id;
2. 表达式
SELECT particle_speed / 2.0 AS half_particle_speed (对结果做了一个除2)
FROM physics_data
WHERE ABS(particle_position) * 10.0 >500
(条件要求这个属性绝对值乘以10大于500);
分组统计:GROUP BY
GROUP BY 数据分组语法可以按某个col_name对数据进行分组,如:GROUP BY Year指对数据按年份分组, 相同年份的分到一个组里。如果把统计函数和GROUP BY结合,那统计结果就是对分组内的数据统计了.
GROUP BY 分组结果的数据条数,就是分组数量,比如:GROUP BY Year,全部数据里有几年,就返回几条数据, 不管是否应用了统计函数.
HAVING
HAVING 和 WHERE 语法一样,只不过作用的结果集不一样. 在我们例子数据表数据量小的情况下可能感觉 HAVING没有什么用,但当你的数据量成千上万属性又很多时也许能帮上大忙 .
小贴士?
如果你不用GROUP BY
语法, 简单的WHERE
就够用了.
mysql中的when语句
SELECT role ,count(role),(case when Building is null then 0 else 1 end ) bn
from Employees group by Role,bn;
条件:数字(where)
当查找条件col是数字
select * from table where col = 1;
Operator | Condition | SQL Example | 解释 |
---|---|---|---|
=, !=, < ,<=, >, >= | Standard numerical operators | col != 4 | 等于 大于 小于 |
BETWEEN … AND … | Number is within range of two values (inclusive) | col BETWEEN 1.5 AND 10.5 | 在 X 和 X之间 |
NOT BETWEEN … AND … | Number is not within range of two values (inclusive) | col NOT BETWEEN 1 AND10 | 不在 X 和 X之间 |
IN (…) | Number exists in a list | col IN (2, 4, 6) | 在 X 集合 |
NOT IN (…) | Number does not exist in a list | col NOT IN (1, 3, 5) | 不在 X 集合 |
条件:文本(where)
当查找条件col是文本
select * from table where col like ‘%jin’;
Operator | Condition | SQL Example | 解释 |
---|---|---|---|
= | Case sensitive exact string comparison (notice the single equals) | col = “abc” | 等于 |
!= or <> | Case sensitive exact string inequality comparison | col != “abcd” | 不等于 |
LIKE | Case insensitive exact string comparison | col LIKE “ABC” | 等于 |
NOT LIKE | Case insensitive exact string inequality comparison | col NOT LIKE “ABCD” | 不等于 |
% | Used anywhere in a string to match a sequence of zero or more characters (only with LIKE or NOT LIKE) | col LIKE “%AT%” (matches “AT”, “ATTIC”, “CAT” or even “BATS”) | 模糊匹配 |
_ | Used anywhere in a string to match a single character (only with LIKE or NOT LIKE) | col LIKE “AN_” (matches “AND”, but not “AN”) | 模糊匹配单字符 |
IN (…) | String exists in a list | col IN (“A”, “B”, “C”) | 在集合 |
NOT IN (…) | String does not exist in a list | col NOT IN (“D”, “E”, “F”) | 不在集合 |
排序(rows)
需要对结果rows排序和筛选部分rows
select * from table where col > 1 order by col asc limit 2 offset 2
Operator | Condition | SQL Example | 解释 |
---|---|---|---|
ORDER BY | . | ORDER BY col ASC/DESC | 按col排序 |
ASC | . | ORDER BY col ASC/DESC | 升序 |
DESC | . | ORDER BY col ASC/DESC | 降序 |
LIMIT OFFSET | . | LIMIT num_limit OFFSET num_offset | 从offset开始取limit(不包括offset) |
ORDER BY | . | ORDER BY col1 ASC,col2 DESC | 多列排序 |
join:连表(table)
当查找的数据在多张关联table里
select * from table1 left join table2 on table1.id = table2.id where col > 1
Operator | Condition | SQL Example | 解释 |
---|---|---|---|
JOIN … ON … | . | t1 JOIN t2 ON t1.id = t2.id | 按ID连成1个表 |
INNER JOIN | . | t1 INNER JOIN t2 ON t1.id = t2.id | 只保留id相等的row |
LEFT JOIN | . | t1 LEFT JOIN t2 ON t1.id = t2.id | 保留t1的所有row |
RIGHT JOIN | . | t1 RIGHT JOIN t2 ON t1.id = t2.id | 保留t2的所有row |
IS/IS NOT NULL | . | col IS/IS NOT NULL | col是不是为null |
算式(select / where)
当需要对select的col 或 where条件的col 经过一定计算后才能使用
select * , col*2 from table where col/2 > 1
Operator | Condition | SQL Example | 解释 |
---|---|---|---|
(+ - * / %) | . | col1 + col2 | col加减乘除 |
substr | . | substr(col,0,4) | 字符串截取 |
AS | . | col * 2 AS col_new | col取别名 |
… | 还有很多 |
统计(select)
对查找的rows需要按col分组统计的情况
select count(*),avg(col),col from table where col > 1 group by col
Operator | Condition | SQL Example | 解释 |
---|---|---|---|
COUNT(*), COUNT(column) | A common function used to counts the number of rows in the group if no column name is specified. Otherwise, count the number of rows in the group with non-NULL values in the specified column. | count(col) | 计数 |
MIN(column) | Finds the smallest numerical value in the specified column for all rows in the group. | min(col) | 最小 |
MAX(column) | Finds the largest numerical value in the specified column for all rows in the group. | max(col) | 最大 |
AVG(column) | Finds the average numerical value in the specified column for all rows in the group. | avg(col) | 平均 |
SUM(column) | Finds the sum of all numerical values in the specified column for the rows in the group. | sum(col) | 求和 |
GROUP BY | . | group by col,col2 | 分组 |
HAVING | . | HAVING col>100 | 分组后条件 |
插入值必须按照顺序、数量、类型、约束条件,否则语法不通过
如果表名后不加列,表示插入所有列记录
INSERT INTO table_name[(column[,column...])] VALUES (value[,value...])
INSERT INTO 子查询
删除表中记录,DELETE后可加FROM,也可省略,删除记录,应从子表先开始删除,否则报错,不能删除被其他表引用的数据
,删除还应注意联合外键的情况(Oracle可以不加from)
删除表中所有数据
DELETE FROM 表名;
删除满足条件的数据
DELETE FROM 表名 WHERE 条件;
更新表中记录,不加WHERE子句,表示这字段所有记录的内容均被修改
改所有
UPDATE TABLE_NAME SET 字段=’‘
将此字段满足条件的记录修改
UPDATE TABLE_NAME SET 字段=’‘WHERE 条件
指一系列DML操作的集合,不同窗口进行DML操作,不会直接作用到数据库服务,相当于SVN中的本地操作,只有事务结束才会作用到数据库服务。
注意:回滚只能从后向前,不能从前向后,后指的是后设置的后滚点,前指的是前一个设置的回滚点
- TRUNCATE不能回滚,DELETE可以回滚
- 在删除大量数据时,TRUNCATE比DELETE快
- TRUNCATE可以释放表空间,DELETE不可以释放表空间(表空间为逻辑空间)
- TRUNCATE操作对象只能是表,DELETE可以是表、视图、同义词
= TRUNCATE是DDL语句,DELETE是DML语句
表命名规则:以字母开头、长度限制为30字符、内容组成为:A-Z、a-z、0-9、_、$和#、不能为oracle保留字、同一用户下不能重名、不能和用户定义的其他对象重名
--VARCHAR2(size) 内存空间大小是随着存储值的长度而变化,其长度需要小于等于size的值,varchar数据类型会自动转换成varchar2类型
--CHAR(size) 内存空间大小为size的值,是固定的,不会随着存储的值长度变化而变化,不建议使用
--NUMBER(size) 数值有效位数为size的值
--NUMBER(p、s) p为数值的有效数字位,s为小数位数
--DATE 日期类型
--CLOB 可变的内存空间,存储大数据字符串,最高可存储2GB
--BLOB 存储较大的二进制数据,如图片等
--PRIMARY KEY 主键约束 PK --FOREIGN KEY 外键约束 FK --UNIQUE 唯一约束 表名_列名_UK --NOT NULL 非空约束 NN --CHECK 检查约束 表名_列名_CK --不命名约束,oracle会自动产生特定的约束,名字以sys_为前缀 CONSTRAINT自定义约束(行业规范,必须自定义) 优点:通过约束的名称了解此约束是作用在哪张表、哪个字段,以及是什么类型的约束 --约束可以在表级别和列级别上定义 --列级别:约束类型紧跟在列后,约束和列间没有逗号分隔 --表级别:约束和列间通过逗号分隔,NOT NULL不能加在表级别上 自定义约束名 表名_字段名_约束缩写 约束名 外键约束 外键加在表级别上 constraint 自定义的约束名 foreign key(字段名) references 主表名(主表的主键) 外键加在列级别上 constraint 自定义的约束名 references 主表名(主表的主键) 联合主键 需要两个字段遵循 联合唯一 、联合非空
类型 | 类型举例 |
---|---|
整数 | TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)、BIGINT |
浮点 | FLOAT、DOUBLE |
定点数 | DECIMAL |
位类型 | BIG |
日期时间类型 | YEAR、TIME、DATETIME、TIMESTAP |
文本字符串 | CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT |
枚举类型 | ENUM |
集合类型 | SET |
二进制字符串类型 | BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB |
json类型 | JSON对象、JSON数组 |
空间数据类型 | 单值类型:GEOMETRY、POINT、LINESTRING、POLYGON; 集合类型:MULTIPOINT、MULTILINESTRING、MULTPOLYGON、GEOMETRYCOLLECTION |
mysql关键字 | 含义 |
---|---|
NULL | 数据列可包含NULL值 |
NOT NULL | 数据列不允许包含NULL值 |
DEFAULT | 默认值 |
PRIMARY KEY | 主键 |
AUTO_INCREMENT | 自动递增,适用于整数类型 |
UNSIGNED | 无符号 |
CHARACTER SET name | 指定一个字符集‘utf8’(数据库、表、字段都可以指定) |
注意:1.显示宽度与类型可存储的范围无关。2.后面结合使用ZEROFILL,表示显示宽度不足的前面用0补齐
浮点数是不准确的,所以避免使用 “=”来判断两个数是否相等。所以精确的数据类型使用decimal
使用CURRENT_TIME()或者NOW()插入当前系统的时间
OPTIMIZE TABLE
功能对这类表进行碎片整理# 库操作(增、删、改、查)
create database 库名
drop database 库名
alter 库名
show databases
# 表操作
create table ...(
username varchar;
password varchar;
);
windows:C:\ProgramData\Mysql\Mysql Server8.0\Data
linux: /var/lib/mysql/
mac os: /usr/local/mysql/data
# 点击进入阿里云进行镜像加速后
# 再进行如下操作
docker search mysql
docker pull mysql
docker images
1. 启动快捷方式
docker run --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
2. (配置容器MySQL数据、配置、日志挂载宿主机目录)
# 宿主机创建数据存放目录映射到容器
mkdir /usr/local/docker_data/mysql/data
# 宿主机创建配置文件目录映射到容器
mkdir /usr/local/docker_data/mysql/conf # (建议在此目录创建my.cnf文件并进行相关MySQL配置)
# 宿主机创建日志目录映射到容器
mkdir /usr/local/docker_data/mysql/logs
docker run --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d -v /usr/local/docker_data/mysql/data:/var/lib/mysql -v /usr/local/docker_data/mysql/conf:/etc/mysql/ -v /usr/local/docker_data/mysql/logs:/var/log/mysql mysql:5.7
docker exec -it mysqlserver bash
mysql -uroot -p
开启远程访问权限
use mysql;
select host,user from user;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges;
# 下载ifconfig
apt update
apt install net-tools
#更新apt-get库 sudo apt-get update #安装mysql sudo apt-get install mysql-server (-y) #初始化配置mysql sudo mysql_secure_installation sudo mysql -u root -p use mysql; select host,user,plugin from user; # 配置远程连接 update user set host='%' , plugin='mysql_native_password' where user='root'; # 授予root用户全部权限 grant all privileges on *.* to 'root'@'%' with grant option; flush privileges; vim /etc/mysql/mysql.conf.d/mysqld.cnf #注释掉#bind-address =127.0.01,或者将其修改为0.0.0.0 # 查看mysql的服务状态 systemctl status mysql netstat -ntlp (可看运行的端口号) netstat -tap | grep mysql # 查看版本号 sudo mysql --version mysql -V # 如果没有设置密码,查看密码,password sudo cat /etc/mysql/debian.cnf # 配置远程连接 sudo mysql -u root -P use mysql; select host,user,plugin from user; update user set host='%' , plugin='mysql_native_password' where user='root'; flush privileges; ## 修改配置文件 vim /etc/mysql/mysql.conf.d/mysqld.cnf 将bind-address= 127.0.0.1注释,或修改为0.0.0.0
# 查看默认使用的字符集
show variables like 'character%';
# mysql5.7默认是latin,mysql8默认是utf8mb4
字符集的与比较规则(了解)
show charset
;#查看服务器的字符集和比较规则
show variables like '%_server';
# 查看数据库的字符集和比较规则
show variables like '%_database';
# 查看具体数据库的字符集
show create database ....;
# 修改具体数据库的字符集
alter database ... default character set 'utf8' collate 'utf8_general_ci'
一对多:在多的一方设置外键,关联一的一方的主键
多对多:建立第三张表中间表,中间表至少包含两个外键,分别关联两个表的主键
一对一:第二张表相当于第一张表的拓展表,第二张表的外键有unique属性。
sql 语句
union(union all)
sql语句
是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
查看/设置事务提交方式:SELECT @@autocommit;
SET @@autocommit=0;
开启事务:START TRANSACTION 或 BEGIN
提交事务: COMMIT
回滚事务: ROLLBACK
1.脏读:一个事务读到另外一个事务还没有提交的数据
2.不可重复读:一个事务先后读取到同一条记录,但两次读取的数据不同,称之为不可重复读
3.幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了幻影。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | √ | √ | √ |
read committed | × | √ | √ |
repeatable read(默认) | × | × | √ |
serializable(串行化) | × | × | × |
--查看事务隔离级别
select @@transaction_isolation;
--设置事务隔离级别
set [session|global] transaction isolation level [read uncommitted | read committed | repeatable read | serializable]
存储引擎就是存储数据、建立索引】更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型。
- 查看表存储引擎(默认是innoDB)
show create table table_name;
- 查看数据库所有支持的引擎
show engines;
InnoDB
事务
;行级锁
,提高并发访问性能;支持外键
FOREIGN KEY约束,保证数据的完整性和正确性。show variables like 'innodb_file_per_table';
查看MyISAM
Memory
Archive引擎:用于数据存档(不可修改)
对比项 | MyISAM | InnoDB |
---|---|---|
外键 | 不支持 | 支持 |
事务 | 不支持 | 支持 |
行表锁 | 表锁 ,即使操作一条记录也会锁住整个表,不适合高并发的操作 | 行锁 ,操作时只锁某一行,不对其他行有影响,适合高并发的操作 |
缓存 | 只缓存索引,不缓存真实数据 | 不仅缓存索引还要缓存真实数据,对内存要求较高 ,而且内存大小对性能有决定性的影响 |
自带系统表使用 | Y | N |
关注点 | 性能:节省资源、消耗少、简单业务 | 事务:并发写、事务、更大资源 |
默认安装 | Y | Y |
默认使用 | N | Y |
索引(index)是帮助mysql高效获取数据
的数据结构(有序)
。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
优势 | 劣势 |
---|---|
提高数据检索的效率,降低数据库的io成本 | 索引列也是要占空间的 |
通过索引列对数据进行排序,降低数据排序的成本,降低cpu的消耗 | 索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行insert、update、delete时,效率降低 |
mysql的索引是在存储引擎层实现的,不同的存储引擎有不同的结构
索引结构 | 描述 | 支持的存储引擎 |
---|---|---|
B+tree索引 | 最常见的索引类型,大部分引擎都支持B+树索引 | InnoDB、MyISAM、Memory |
hash索引 | 底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询 | Memory |
R+tree(空间索引) | 空间索引是MYISAM引擎的一个特殊索引类型,主要用于地理空间数据类型 | MyISAM |
FULL-text(全文索引) | 是一种通过建立倒排索引,快速匹配文档的方式,类似于Lucene,Solr,ES | InnoDB(5.6之后)、MyISAM |
B+tree树
所有的元素都会出现在叶子节点。
mysql索引数据结构对经典的b+tree进行了优化。在原b+tree的基础上,增加了一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的b+tree,提高区间访问的性能。
hash
哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
如果两个(或多个)键值,映射到了一个相同的槽位上,他们就产生了hash冲突(碰撞),可以采用链表来解决
面试问题
为什么InnoDB存储引擎选择使用B+tree索引结构
分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | FULLTEXT |
在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:
分类|含义|特点
聚集索引(clustered index)|将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据|必须有,而且只有一个
二级索引(secondary)|将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键|可以存在多个
所以根据主键字段进行查询的效率,大于根据一般字段进行查询的效率(一般查询,先查询到主键,再进行回表查询)
查看当前数据库的insert、update、delete、select的访问频次。
show [session | global] status like ‘com_______’;
慢查询日志记录了所有执行时间超过指定指定参数(long_query_time,单位:秒,默认10秒)的所有sql语句的日志。mysql的慢查询日志默认没有开启,需要在mysql的配置文件(/etc/mysql/my.cnf)中配置如下信息(slow_query_log = 1
long_query_time =2 ,但是我失败了,所以我用了下面的方法
)
# 查看慢查询日志是否开启,且日志位置 show variables like '%slow_query_log%'; show variables like '%long_query_time%'; # 开启慢查询日志 set global slow_query_log=ON; # 设置慢查询日志阈值时间 SET GLOBAL long_query_time = 2; 每次修改之后,都需要重新开一个新的会话查询,因为旧的会话查询出来的始终是打开时的值,不会直接同步。 # 设置未使用index的数据也添加到慢查询日志 # 先查看是否打开 show variables like 'log_queries_not_using_indexes'; # 再进行设置 set global log_queries_not_using_indexes=on; 注意:log_queries_not_using_indexes参数要跟参数log_throttle_queries_not_using_indexes配合使用,(og_throttle_queries_not_using_indexes:该参数决定每分钟记录未使用索引的SQL的数量上限,因为未使用索引的SQL可能会非常多,导致慢日志空间增长飞快。) # 打开记录管理的语句 show variables like '%log_slow_admin_statements%'; set global log_slow_admin_statements=1
MySQL5.7慢查询日志时间与系统时间差8小时原因详解
查看日志的时间(显示为UTC)
show [global] variables like ‘log_timestamps’;
设置为系统时间
SET GLOBAL log_timestamps = SYSTEM;
show profilen能够在做sql优化时帮助我们了解时间都耗费到哪里去了。
# 查看当前数据库是否支持profile操作
select @@hava_profiling;(但是我执行报错了)
# 查看是否开启profiling
select @@profiling;
# 默认profiling是关闭的,可以通过set语句在session/global级别开启profiling
set profiling = 1;
执行一系列的业务sql的操作,然后通过如下指令查看指令的执行耗时:(好像不支持了
)
# 查看每一条sql的耗时基本情况
show profiles;
# 查看指定query_id的sql语句各个阶段的耗时情况
show profile for query query_id;
# 查看指定query_id的sql语句cpu的使用情况
show profile cpu for query_id;
explain 或者desc 命令获取mysql如果执行select语句的信息,包括select语句执行过程中表如何连接和连接的顺序。
语法:直接在select 语句之前加上关键字explain/desc
explain执行计划各字段含义:
#在未建立索引之前,执行如下sql语句,查看sql的耗时,耗时时间为10秒
select * from tb_sku where sn='1232';
# 针对sn字段创建索引
create index idx_name on tb_sku(sn);
# 然后再进行查询,时间变为0.01sec。
联合索引
),要遵循最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效)。索引将失效
use index:建议用此索引
ignore index:忽略
force index:强制
explain select * from tb_user force_index(idx_user_id) where id='1';
尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引(二级索引)中已经全部能够找到),减少select 。
例如:extra字段中-using index condition/null表示查找使用了索引,但是需要回表查询数据。
using where;using index表示查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据。
面试题:一张表,有四个字段(id,username,password,status),由于数据量大,需要对以下sql语句进行优化,该如何进行才是最优方案:
** select id,username,password from tb_user where username=‘sober’;*
对username和password建立一个联合索引,避免回表操作
当字段类型为字符串(varchar,text等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘io,影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。
语法:create index idx_xxx on table_name(column(n));
前缀长度:
可以根据索引的选择性来决定,而选择性时指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。
求选择性的数值
select count(distinct name)/count(*) from sale_client;
select count(distinct substring(name,1,4)) / count(*) from sale_client;
单列索引:即一个索引只包含单个列
联合索引:即一个索引包含了多个列
在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引,而非单列索引。
1.针对于数据量较大(一百万以上),且查询比较频繁的表建立索引
2.针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引
3.尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高
4.如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引
5.尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
6.要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率,占用磁盘空间
7.如果索引列不能存储null值,请在创建表时使用not null约束它。当优化器知道每列是否包含null值时,它可以更好的确定哪个索引最有效地用于查询。
# 客户端连接服务端时,加上参数--local-infile
mysql --local-infile -u root -P
# 查看local_infile 的参数
select @@local_infile;
# 设置全局参数local_infile 为 1,开启从本地加载文件导入数据的开关
set global local_infile =1 ;
# 查看数据有几行
wc -l xxx
# 执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/xxxx' into table 'table_name' fields teminated by ',' lines teminated by '\n';
主键顺序插入性能高于乱序插入
IOT
)主键乱序插入的情况下
)# 创建一个升序,一个降序的索引
create index idx_age_ptone_ad on tb_user(age asc ,phone desc);
1.根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则
2.尽量使用覆盖索引
3.多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)
4.如果不可避免的出现filesort,大数据排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256k),(show variables like ‘sort_buffer_size’
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。