假如where条件后面有abc三个条件 如何加索引 5个呢
- 使用联合索引
- 联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。
- 注意事项
- 命名规则:表名_字段名
1、需要加索引的字段,要在where条件中
2、数据量少的字段不需要加索引
3、如果where条件中是OR关系,加索引不起作用
4、符合最左原则
- 命名规则:表名_字段名
ALTER TABLE `table_name` ADD INDEX (`col1`,`col2`,`col3`);
比如:有个联合索引(name,age)
select * from table where name='' 生效
select * from table where name='' and age=1 生效
select * from table where age=1 不生效(不符合最左原则,没有最左边的name条件)
select * from table where age=1 and name='' 生效(mysql优化器做了优化,自动转为了name='' and age=1)
索引优先建立在什么上面,如何调优
- 定义主键的数据列一定要建立索引。
- 定义有外键的数据列一定要建立索引。
- 对于经常查询的数据列最好建立索引。
- 对于需要在指定范围内的快速或频繁查询的数据列;
- 经常用在WHERE子句中的数据列。
- 经常出现在关键字order by、group by、distinct后面的字段,建立索引。
如何判断sql是否走索引
explain关键字会使用吗
varchar(20)可以输入几个汉字
-
4.0版本以下,varchar(100),指的是100字节,如果存放UTF8汉字时,只能存33个(每个汉字3字节)
-
5.0版本以上,varchar(100),指的是100字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放100个。
FIND_IN_SET函数的用法
-
FIND_IN_SET(str,strlist)
假如字符串str 在由N 子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。
一个字符串列表就是一个由一些被‘,’符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则 FIND_IN_SET() 函数被优化,使用比特计算。
如果str不在strlist 或strlist 为空字符串,则返回值为 0 。如任意一个参数为NULL,则返回值为 NULL。这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
时间计算函数
-
TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)
SECOND:秒 MINUTE:分钟 HOUR:小时 DAY:天 WEEK:星期 MONTH:月 QUARTER:季度 YEAR:年 datetime_expr1: 要比较的日期1 datetime_expr2: 要比较的日期2
--相差1分钟
select TIMESTAMPDIFF(MINUTE,'2022-02-02 12:01:02','2022-02-02 12:02:02')
ONLY FULL GROUP BY报错
- 原因
-
MySql从5.7版本开始默认开启only_full_group_by规则,规则核心原则如下,没有遵循原则的sql会被认为是不合法的sql
-
order by后面的列必须是在select后面存在的
-
select、having或order by后面存在的非聚合列必须全部在group by中存在
- 解决方法
-
第一种,修改sql使其遵守only_full_group_by规则
-
第二种,将MySql的版本降到5.7以下
-
第三种,关闭only_full_group_by规则(推荐使用,但是重启mysql服务后就失效了)
查询当前模式:
select @@global.sql_mode
SELECT @@SESSION.sql_mode;
重新设置模式:
set session sql_mode= 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
//修改globalsql
set @@global.sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
Innodb 下的隔离级别
- 数据库的隔离级别分为四个等级:
- read uncommitted(读未提交) ,事务A可以读取到事务B未提交的数据,事务B回滚,则事务A中的数据为脏数据,就是脏读,数据还没提交就读到了
- read committed(读已提交) ,事务A只能读取到事务B已提交的数据,会产生不可重复读与幻读的问题,就是幻读,读到了已经提交的数据,但是同一事物中,会导致多次读到的结果不一样
- repeatable read(可重复读),解决了不可重复读的问题,但幻读依然存在
- serializable(串行读)
- 默认的隔离级别是可重复读
开启事务,同时操作一条数据会怎么样
两个事务,当事务A开启后查询一条数据,得到结果为2,在这过程中事务b修改了数据为2并提交了,这时候事务A再次查询,得到的结果是多少
- 结果是2,MySQL在同一个事务中,多次查询的同一个值的结果是不会变的,即使这个值被其他的事务改变过
json 相关
SELECT
jt.key_id,
jt.key_kind
FROM
cmdb_template_unique_check t,
JSON_TABLE ( keys
, ‘
[
∗
]
′
C
O
L
U
M
N
S
(
k
e
y
i
d
B
I
G
I
N
T
P
A
T
H
′
[*]' COLUMNS ( key_id BIGINT PATH '
[∗]′COLUMNS(keyidBIGINTPATH′.key_id’, key_kind VARCHAR ( 32 ) PATH ‘$.key_kind’ ) ) AS jt where t.template_id=1 and jt.key_id in(1,2)