MySQL索引优化(超详细)

2023-11-18

Mysql索引优化

1 索引介绍

1.1 什么时MySQL的索引

​ MySQL官方对于索引的定义:索引是帮助MySQL高效获取数据的数据结构。
​ MySQL在存储数据之外,数据库系统中还维护着满足特定查找算法的数据结构,这些数据结构以某种引用(指向)表中的数据,这样我们就可以通过数据结构上实现的高级查找算法来快速找到我们想要的数据。而这种数据结构就是索引。
​ 简单理解为“排好序的可以快速查找数据的数据结构”。

1.2 索引数据结构

1.⼆叉树查找

​ 我们都学过⼆分查找,如果我们⼀开始在插⼊数据就将数据按顺序排列,那查找效率就会⼤⼤提⾼。将数据按照顺 序⼆叉树排列好每次查询就可以使⽤⼆分法即从根节点出发,查询效率就增加了

image-20230510170457449

但是如果删除了⼀些数据⽐如0,6,1,3,4删除了那么右边的数据就有变成了线性的了,查询效率就会有所浪 费

image-20230510170509932

2 平衡二叉树

​ 如果有这样⼀棵树左右⼦树⾼度差不超过 1,⽽且也满⾜顺序排列就可以继续⾼效下去,然后平衡⼆叉树就出现 了。每当删除⼀个节点都应该发⽣相应的节点位置转换反转保证⼆叉树的平衡。

image-20230510170647274

​ 说了这么多我们⽆⾮就是想让查找效率变高,从线性的 O(n) 到 O (logn),好像还有疑问为什么不⽤更⾼效的 Hash 地址法来查找呢?这样可以降到 O(1),答案是在查询过程中我们不仅有等值查询还有范围查询 模糊查 询,使⽤ Hash 存储其位置的不确定性,如果要查询 范围我们就要遍历全表。⽽⼆叉树只要遍历左右节点。

3.B树

​ 由于平衡⼆叉树的⼆叉特点,它每⼀个节点最多只有 2 个叉,假设有 100000 个数据,那么树的深度将会变得特别 深,⽽每次⽐较就是拿⽐较的树和节点上的数在内存⽐较,所以每⽐较⼀次就是⼀次 IO 操作就下降⼀层,层数越 多时间就越久。所以B树就来了,他是多叉平衡树,每个节点维护了多个⽐较范围(即⼦节点)

image-20230510170729722

​ 这样就降低了⾼度,每个圆圈可以理解为⼀⻚,16kb的数据. 所以他的每个节点都存储数据就会造成每个结点的分 叉数减少,⽽且会造成先靠近根节点的先查到,靠近叶⼦结点的后查到。同样范围查找也会出现多次回退到⽗节点 在到另⼀个兄弟节点的低效率问题。

4.B+树

​ 我们改造⼀下 B树 为 B + 树 ,每个⾮叶⼦节点只存索引,真实数据都存在叶⼦节点,这样⾮叶⼦节点的空间 单个 数据空间 减少 数量即分叉就可以增⼤。每次查询⽆论如何必须遍历到叶⼦节点才会结束,这样深度⼜减少了,同 时我们把每个叶⼦结点⽤双向链表连接起来,范围查询就更快。

image-20230510170819803

1.3 索引优势

​ 提高数据检索的效率,降低数据库的Io成本。
​ 通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

1.4 索引劣势

​ 索引实际上也是一张表,保存了主键和索引的字段,并且指向实体表的记录,所以索引也索引实际上也是一张表,保存了主键和索引的字段,并且指向实体表的记录,所以索引也是需要占用空间的。在索引大大提高查询速度的同时,却会降低表的更新速度,在对表进行数据增删改的同时,MySQL 不仅要更新数据,还需要保存一下索引文件。每次更新添加了的索引列的字段,都会去调整因为更新带来的减值变化后的索引的信息。

1.5 索引使用场景

哪些情况需要创建索引:

1.主键自动建立唯一索引

2.频繁作为查询条件的字段应该创建索引(where后面的语句)

3.查询中与其它表关联的字段,外键关系建立索引

4.多字段查询下倾向创建组合索引

5.查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度

6.查询中统计或者分组字段

那些情况不推荐建立索引:

1.表记录太少

2.经常增删改的表

3.where条件里用不到的字段

1.6 索引分类

1.6.1 主键索引

1.表中的列设定为主键后,数据库会自动建立主键索引。

2.单独创建和删除主键索引语法:

​ 创建主键索引语法:! alter table表名add primary key (字段);

​ 删除主键索引语法: alter table表名drop primary key;

1.6.2 唯一索引

1.表中的列创建了唯一约束时,数据库会自动建立唯一索引。

2.单独创建和删除唯一索引语法:

​ 创建唯一索引语法: alter table表名add unique索引名(字段);

​ 或create unique index索引名on表名(字段);

​ 删除唯一索引语法: drop index索引名on表名;

1.6.3 单值索引

即一个索引只包含单个列,一个表可以有多个单值索引。

1.建表时可随表一起建立单值索引

2.单独创建和删除单值索引:

​ 创建单值索引: alter table 表名 add index索引名(字段);

​ 或create index 索引名 on 表名(字段);

​ 删除单值索引: drop index索引名on表名;

1.6.4 复合索引

即一个索引包含多个列

1.建表时可随表一起建立复合索引

2.单独创建和删除复合索引:

​ 创建复合索引: create index 索引名 on 表名(字段1,字段2);

​ 或alter table表名 add index索引名(字段,字段2);

​ 删除复合索引: drop index索引名 on 表名;

案例
-- 创建customer表并创建四种索引
create table customer(
	id int(10) auto_increment,
	customer_no varchar(20),
	customer_name varchar(20),
	primary key(id),
	unique idex_customer_no (customer_no),
	key idx_customer_name (customer_name),
	key indx_customer_no_name (customer_no,customer_name)
);

image-20230510172749035

单独创建

-- 创建主键索引
alter table customer add primary key(id);
-- 删除主键索引
alter table customer drop primary key;

-- 创建唯一索引
alter table table customer add unique idx_customer_no (customer_no);
-- 删除唯一索引
drop index idx_customer_no on customer;

-- 创建单值索引
alter table customer add index idx_customer_name(customer_name);
-- 删除单值索引
drop index idx_customer_name on customer;

-- 创建复合索引
alter table customer add index idx_customer_no_name(customer_no,customer_name);
-- 删除复合索引
drop index idx_customer_no_name on customer;
1.7 索引测试
-- 创建存储过程
create procedure insert_person( in max_num int(10))
begin
	declare i int default 0;
	set autocommit = 0;
	repeat
	set i = i +1;
	insert into person (PID,PNAVE,PSEX,PAGE ,SAL) values (i,concat('test ' ,floor(rand()*1000)),I(RANID()0.5,'男','女'),FLOOR((RAND()*100)+10),FLOOR((RAND()*19000)+1000));
	until i = max_num
	end repeat;
	commit;
end;

-- 调用存储过程(30000000)即插入三百万条数据
call insert_person(30000000);

-- 不使用索引,根据pName进行查询(10s+)
select * from person where pname = 'test222';

-- 给pname建立索引
alter table person add index idx_pname(PNAME);

-- 再次查询(0.01s+)
select * from person where pname = 'test222';

2 性能分析

2.1 MySQL常见瓶颈

​ SQL中对大量数据进行比较,关联,排序,分组时CPU的瓶颈。

​ 实例内存满足不了缓存数据或排序等需要,导致产生大量的物理I0。查询数据时扫描过多数据,导致查询效率低。

2.2 Explain

​ 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MYSQL是如何处理SQL语句的,可以用来分析查询语句或是表的结构的性能瓶颈。

​ 其作用:

  1. 表的读取顺序
  2. 那些索引能够使用
  3. 数据读取操作的操作类型
  4. 那些索引被实际使用
  5. 表之间的引用
  6. 每张表有多少行被优化器查询

​ EXPLAIN关键字使用起来比较简单:explain + SQL语句

– 创建四张测试表

CREATE TABLE t1(
	id INT(10) AUTO_INCREMENT,
	content VARCHAR(100),
	PRIMARY KEY(id)
);

CREATE TABLE t2(
	id INT(10) AUTO_INCREMENT,
	content VARCHAR(100),
	PRIMARY KEY(id)
);

CREATE TABLE t3(
	id INT(10) AUTO_INCREMENT,
	content VARCHAR(100),
	PRIMARY KEY(id)
);

CREATE TABLE t4(
	id INT(10) AUTO_INCREMENT,
	content VARCHAR(100),
	PRIMARY KEY(id)
);
-- 每张表中添加一条数据(拼接一个以t{{num}}__开头的1-1000的字符串)
INSERT INTO t1(content) VALUES(CONCAT('t1_',FLOOR(1+RAND()*1000)));

INSERT INTO t2(content) VALUES(CONCAT('t2_',FLOOR(1+RAND()*1000)));

INSERT INTO t3(content) VALUES(CONCAT('t3_',FLOOR(1+RAND()*1000)));

INSERT INTO t4(content) VALUES(CONCAT('t4_',FLOOR(1+RAND()*1000)));

2.3 Explain 重要字段

2.3.1 id
  • id相同时,执行顺序是从上往下

    explain select * from t1,t2,t3 where t1.id = t2.id = t3.id;
    

image-20230509141903500

  • id不同时,id的序号会递增,id的值越大优先级越高,则先被执行

    explain select t1.id from t1 where t1.id in
    (select t2.id from t2 where t2.id in
    (select t3.id from t3 where t3.id = 1)
    );
    

image-20230509142004170

  • id相同和不同都存在时,id相同的可以理解为一组,从上往下执行,所有组中,id值越大,优先级越高

    explain select t2.* from t2,(select * from t3) as s3 where s3.id = t2.id; 
    

    image-20230509142024807

2.3.2 select_type
  • SIMPLE :简单的select查询,查询中不包含子查询或者UNION

    explain select * from t1;
    

    image-20230509141831830

  • PRIMARY:查询中若包含任何复杂的子部分,最外层的查询则会被标记为PRIMARY

    explain select *from (select t1.content from t1) as s1;
    

    image-20230509141816279

  • DERIVED:在FROM列表中包含的子查询表被标记为DERIVED,MySQL会递归执行这些子查询,把结果放到临时表中

    explain select *from (select t1.content from t1) as s1;
    

  • SUBQUERY:在SELECT或者WHERE列表中包含了子查询

2.3.3 table:查询⽤到的表名
2.3.4 Type

​ ★连接的类型,常⻅的类型有(性能从好到差)

  • system:存储引擎能够直接知道表的⾏数(如 MyISAM)并且只有⼀⾏数据

    explain select * from (select t1.id from t1 where id = 1) t;
    

    image-20230509164258648

  • const:通过索引⼀次找到,通常在⽤主键或唯⼀索引时出现

     explain select id from t1 where id = 1;
    

    image-20230509164350106

  • eq_ref:⽤主键或唯⼀索引字段作为连接表条件

    explain select t1.*,t2.*
    from t1 
    join t2
    on t1.id = t2.id;
    

    image-20230509164514279

  • ref:⽤普通索引的字段作为连接表条件

    -- 创建普通索引
    alter table t1 add index idx_t1_content(content);
    -- 进行查询
    explain select *from t1 where t1.content = 'abc';
    

    image-20230509164835925

  • range:对索引列进⾏范围查询

    explain select * from t2 where t2.id > 1;
    

    image-20230509164930158

  • index:利⽤索引扫描全表

    -- 因为我们前面给t1的content字段建立了普通索引
    -- 加上主键id为主键索引,所有为查询的所有字段都有索引
    explain select * from t1;
    

    image-20230509165022676

  • all:全表扫描

    explain select * from t1 where content = '132';
    

2.3.5 possible_keys

​ 显示可能应用在这张表的索引,一个或者多个,查询涉及到的字段上如果存在索引,则该索引将会被列出来,但不一定会用到,因为存在索引失效的情况

-- 索引失效了,所以key没有使用到主键索引
explain select * from t2 where id is not null;

image-20230509170103671;

2.3.6 key

​ ★查询中实际使用的索引,如果为null,则表示没有使用索引

2.3.7 ref

​ 当使⽤索引等值查询时,与索引作⽐较的列或常量

-- t2,t3二个表的id为主键索引,查询t3的数据时用到t2的id字段
-- 所以ref为 db_test.t2.id
explain select t2.*,t3.* from t2,t3 where t2.id = t3.id;

image-20230509165611281

2.3.8 row

​ ★预计扫描的⾏数,值越⼤,查询性能越差

-- 前面的插入的三百万数据的person表
explain select * from person where sal = 111;

image-20230509165353829

2.3.9 Extra

​ ★:有关查询执⾏的其他信息

  • using index:使⽤覆盖索引,不⽤回表查询

  • using where:使⽤ where ⼦句来过滤结果集

  • using temporary:使⽤到临时表来存储中间结果,可能会导致性能问题

  • using filesort:查询需要进⾏⽂件排序操作,可能会导致性能问题

  • using index condition:先根据能⽤索引的条件获取符合条件的数据⾏,然后在根据其他条件去过滤数剧

3 查询优化

3.1 索引失效

-- 建立一张学生表
drop table if exists students;
CREATE TABLE students (
	id INT PRIMARY KEY AUTO_INCREMENT COMMENT "主键id",
	sname VARCHAR(24) COMMENT '学生姓名',
	age INT COMMENT '年龄',
	score INT COMMENT '分数',
	time TIMESTAMP COMMENT '入学时间'
 );
-- 插入四条数据
INSERT INTO students(sname,age,score,time) VALUES('小明',22,100,now());
INSERT INTO students(sname,age,score,time) VALUES('小红',23,80,now());
INSERT INTO students(sname,age,score,time) VALUES('小绿',24,80,now());
INSERT INTO students(sname,age,score,time) VALUES('小黑',23,70,now());

-- 创建sname,age,score的组合索引
alter table students add index idx_sname_age_score(sname,age,score);
-- 索引成功(查询索引字段越多,用到的索引越充分,查询越快)
explain select * from students where sname = '小明' and age = 22 and score = 100;
explain select * from students where sname = '小明' and age = 22;
explain select * from students where sname = '小明';
  • 最佳左前缀匹配原则:如果索引了多例,要遵循最左前缀原则,查询从最左前列开始并且不跳过索引中的列

    -- 索引失败
    explain select * from students where age = 22 and score = 100;
    explain select * from students where age = 22;
    
    -- 以下查询都只用到了sname索引
    explain select * from students where sname = '小明';
    explain select * from students where sname = '小明' and score = 22;
    
  • 不在索引列上做任何计算、函数操作,会导致索引失效从而转向全表扫描

    -- 函数操作
    explain select * from students where left(sname,2) = '小明';
    
    -- 不做任何计算
    explain select * from students where sname;
    
  • 存储引擎中不能使用索引中范围条件右边的列

    -- 二个查询都只使用到了snam和age索引
    explain select * from students where sname = '小明' and age > 22 and score = 100;
    explain select * from students where sname = '小明' and age = 22;
    
  • MySQL在使用不等于和is not null无法使用索引

    -- 使用了 !=
    explain select * from students where sname != '小明';
    -- 使用了 is not null;
    explain select * from students where sname is not null;
    
  • like以通配符开头会使索引失效导致全表扫描

-- 索引成功,不是以通配符开头
explain select * from students where sname like '小%';
-- 索引失效,以通配符开头
explain select * from students where sname like '%明';
  • 字符串字段不加单(双)引号
-- 字符串字段sname没有加单(双)引号
explain select * from students where sname =123;
  • 使用or连接索引失效

    -- 使用or连接索引失效
    explain select * from students where sname = '小明' or score = 22;
    

建议:

  1. 对于单值索引,尽量选择针对当前查询字段过滤性更好的索引。

  2. 对于组合索引,当前where查询中过滤性更好的字段在索引字段顺序中位置越靠前越好。

  3. 对于组合索引,尽量选择能够包含在当前查询中 where子句中更多字段的索引。

  4. 尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。

3.2 单表优化

-- 创建文章表
CREATE TABLE IF NOT EXISTS article (
id INT(10) PRIMARY KEY AUTO_INCREMENT,author_id INT(10)NOT NULL,
category_id INT(10) NOT NULL,views INT (10)NOT NULL,
comments INT(10) NOT NULL,
title VARBINARY(255) NOT NULL,content TEXT NOT NULL
);
-- 插入测试数据
INSERT INTO article(author_id,category_id,views,comments,title,content) VALUES
(1,1,1,1,'1','1'),
(2,2,2,2,'2','2'),
(3,3,3,3,'3','3');

案例

1.查询category_id为1的,且comments大于1的情况下,views最多的id和author_id的信息

-- 普通查询,没有使用到索引
explian select id,author_id
from article 
where category_id = 1 and commnts >1 order by view desc limit 1;

2.建立索引

-- 建立文章id,文章和内容的联合索引
alter table article add index idx_ccv(category_id,comments,views );

3.再次查询

-- 以为comments使用了范围查询,所以view没有使用索引查询
explian select id,author_id
from article 
where category_id = 1 and commnts >1 order by view desc limit 1;

4.再次优化

-- 删除组合索引中的comment字段
drop index idx_ccv on article;
alter table article add index idx_cv(category_id,views);

5.再次测试

explian select id,author_id
from article 
where category_id = 1 and commnts >1 order by view desc limit 1;

3.3 关联查询优化

  1. ​ 内连接时,mysql.会自动把小结果集的选为驱动表,所以大表的字段最好加上索引。
  2. ​ 左外连接时,左表(驱动表)会全表扫描,所以右边大表字段最好加上索引。
  3. ​ 右连接同理,我们最好保证被驱动表上的字段建立索引。
-- 创建class表和book表
CREATE TABLE IF NOT EXISTS class (
id INT(10) AUTO_INCREMENT,
card INT(10),
PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS book (
bookid INT(10) AUTO_INCREMENT,
card INT(10),
PRIMARY KEY (bookid)
);
-- 给class和book分别插入十条随机数据
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));

INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));

1.连表查询

-- card没有建立索引,二张表走的都是全表查询
explain select *
from class
left join book
on class.card = book.card;

2.建立索引

-- 右边被驱动表查询字段建立索引
alter table book add index idx_card(card);

3.再次查询

-- 左外连接时,左边的表会进行全表扫描
-- 由外连接同理
explain select *
from class
left join book
on class.card = book.card;

image-20230510164409617

3.4 排序优化

  1. 尽量避免使用Using FileSort方式排序。

  2. order by语句使用索引最左前列或使用where子句与order by子句条件组合满足索引最左前列。

  3. where子句中如果出现索引范围查询会导致order by索引失效

-- order by能使用索引的最左前缀
ORDER BY sname;
ORDER BY sname,socre;
ORDER BY sname,score,age;
-- 降序或者升序要统一
ORDER BY sname DESC,score DESC,age DESC;
--  如果where使用了索引的最左前缀定义为常量,则order by能够使用索引
WHERE sname = const ORDER BY score age;
WHERE sname = const AND score  = const ORDER BY  age;
WHERE sname = const ORDER BY score age;
WHERE sname = const AND score > const ORDER BY score age;
-- 不能使用索引进行排序
-- 排序不一致
ORDER BY sname ASC,score DESC;
--  slike没有添加进索引
WHERE  slike = const ORDER by sname,score;
--  查询age没有使用到索引
WHERE  sname= const ORDER by age;
-- slike没有使用到索引
WHERE  sname= const ORDER by sname,slike;
--  in也是范围查询,score,age没有使用到索引查询
WHERE  sname in(...)  ORDER by score,age;

3.5 分组优化

思路和排序优化同

4 慢查询日志

4.1 介绍

​ mysql提供的一种日志记录,记录在mysql中相应时间超过阈值的数据。

4.2 慢查询日志的使用

默认情况下,mysql数据库没有开启慢查询日志,需要手动设置参数

-- 查看是否开启
show variables like '%slow_query_log%';

image-20230509102431455

-- 开启日志
set global slow_query_log = 1;

image-20230509102513339

-- 设置时间(单位为秒)
set global long_query_time = 1;

-- 查看时间
show variables like 'long_query_time%';

image-20230509102858978

-- 执行一条慢查询语句
select * from person where pname = "test1234" and sal = 22;

image-20230509103038328

-- 关闭日志
set global slow_query_log = off;

image-20230509103255534

4.3注意

​ 非调优条件下,一般不建议启动参数,慢查询日志支持将日志写入文件,开启慢查询日志会多少带来一定的性能影响。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL索引优化(超详细) 的相关文章

  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 映射 mysql 中同一个表的多个值

    您好 我必须使用另一个表中的值 id 获取文本值 表 1 包含值 ID 表 2 包含名称和值 ID 表 1 SEVERITY OCCURENCE DETECTABILITY 2 3 4 表 2 id name value 1 Very Hi
  • MySQL:计算日期/时间之间的差异 - 仅在周一至周五“工作周”期间

    我需要计算开始日期 时间和结束日期 时间之间的差异 但是 我只想在 5 天的工作周内执行此操作 不包括周六 周日 做这个的最好方式是什么 我的想法是 从日期开始 我必须获取星期几 如果是工作日 那么我将添加到累加器中 如果不是 那么我不会添
  • 显示标准化数据

    跟进问题 添加 2 个不同表的总和 https stackoverflow com questions 39717541 adding sum from 2 different tables 我创建了3个表 members videos v
  • MySql - 复制监控工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个主 从 MySql 复制 我正在寻找一个允许我监视复制的工具 查看它没有错误 检查滞后等 我更喜
  • 不允许在 php 中连接到此 MariaDB 服务器

    我尝试在 php 中连接远程服务器数据库 但出现以下错误 Host xx xxx xx xx is not allowed to connect to this MariaDB server in 我的连接代码是这样的 servername
  • covertJSONtoSQL 在 NiFi 中返回空值

    我正在设计一项工作 使用以下命令将数据从 MySQL 中的数据库转移到另一个数据库 MySQL 执行SQL处理器随后将Avro转换为Json then 将Json转换为SQL then PutSQL如下流程图所示 将JSON转换为SQL返回
  • MySQL 通过 current_timestamp 选择上个月的数据

    直到今天 当我使用 MySQL 并需要对日期 时间执行操作时 我使用带有 unix 时间戳的 int 列 没有出现任何问题 但今天在阅读了一些指南后 我决定默认使用 current timestamp 测试时间戳列 所以我感兴趣如何按列选择
  • MySQL 8 用逗号分割字符串并将其转换为JSON ARRAY

    我有以下字符串 a b c d 我想将它转换成一个 json 数组 像这样 a b c d MySQL 8 有什么函数可以实现这个功能吗 Try SELECT CAST CONCAT REPLACE a b c d AS JSON See
  • 每月获取记录,但如果该月没有记录,则为零

    如果我有以下 SQL 表 Tests id type receiveDate 1 Blood 2012 01 18 2 Blood 2012 01 20 3 Blood 2012 01 18 4 Blood 2012 03 01 5 Blo
  • 无法在 Mac 上启动 MySQL

    使用 Brew 安装后 我无法运行 MySQL 我使用的是 OS X El Capitan 版本 10 11 3 和 MySQL Server 版本 5 7 11 当我启动服务器时 我收到 启动 MySQL 错误 服务器退出而不更新 PID
  • mysql 中的二进制、十六进制和八进制值

    我对在 mysql 数据库中使用二进制 十六进制和八进制系统非常感兴趣 首先 请给我一个建议 为什么我们在存储信息时需要它们 因为信息太多 或者为什么 另外 哪种类型的值必须存储在标记系统中 另外这里还有像 这是例子 gt SELECT 5
  • 让登录更安全

    我已使用此代码进行管理员登录 仅当用户输入正确的用户名和密码时才应打开loginhome php 但后来我意识到这根本不安全 任何人都可以直接访问 mywebsite loginhome php 而无需登录 注销后 可以使用后退按钮打开 l
  • 如何在 SEQUELIZE (nodeJS) 中创建触发器?

    我正在尝试使用sequelize 创建一个触发器 主要思想是创建一个实例CONFIG创建后USER USER MODEL module exports function sequelize DataTypes var User sequel
  • PHP MySql 百分比

    我的问题是关于百分比 我不是专家 所以我会尽力以更好的方式进行解释 我的 mysql 服务器中有一个表 假设有 700 条记录 如下所示 Name country language Birth Lucy UK EN 1980 Mari Ca
  • 如何检测Mysql/innodb中的死锁?

    我知道在 Innodb 中使用事务时不可避免地会发生死锁 并且如果应用程序代码正确处理死锁 它们是无害的 正如手册所说 只需再试一次 所以我想知道 如何检测死锁 死锁是否会发出一些特殊的 mysql 错误号 如果重要的话 我正在使用 PHP
  • 获取带有计数的不同记录

    我有一张桌子personid and msg列 personid msg 1 msg1 2 msg2 2 msg3 3 msg4 1 msg2 我想得到总计msg对于每个personid 我正在尝试这个查询 select distinct
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • Mysql插入表后不显示右单引号(’)

    我有一个名为 测试 的表 我插入了一行 其中包含unicode字符右单引号 0x2019在名称字段中 SQL insert into Testing values Sno Name Address insert into Testing v
  • 内部 while 循环不工作

    这是我项目网页上的代码片段 这里我想显示用户选择的类别 然后想显示属于该类别的主题 在那里 用户可以拥有多个类别 这没有问题 我可以在第一个 while 循环中打印所有这些类别 问题是当我尝试打印主题时 结果只显示一行 但每个类别中有更多主

随机推荐

  • java 0-9 A-Z进位函数

    java 可以包含数字0 9 和字母A Z的加法编码规则 例如城市编码 2位 可以是0 9 也可以是A Z 那么实际编码顺序则是0 1 2 3 4 5 6 7 8 9 A B C D E F G A9的下一个编码是AA AZ的下一个编码是B
  • html背景毛玻璃效果代码,css3毛玻璃效果(背景虚化)

    wrap h3 font size 18px color ffffff wrap p font size 14px color ffffff font variant ligatures common ligatures discretio
  • 人工智能--深度学习两层全连接神经网络搭建

    系列文章目录 人工智能 深度学习从感知机到神经网络 人工智能 深度学习神经网络神经元的实现 文章目录 系列文章目录 前言 一 多层神经网络的结构 二 两层全连接神经网络 1 搭建模型 2 神经元传递理论 3 激活函数的确定 三 神经网络实现
  • exe和dll库分离

    c 在写程序的时候一般会用到第三方库 我们在引用后 一般会把第三方库复制到debug生成的目录下 如果第三方库的dll很少那还可以 如果第三方库的dll很多 那么就会和自己生成的exe混在一起 看着极其混乱 所以有时候会把第三方库文件单独的
  • 高端算法总结

    1 合并排序 2 两次筛选 3 BANSAC 4 动态规划 5 Karatsuoa 乘法 6 快速傅里叶变换 7 最大流量算法 8 learing学习算法 9 RSA 10 Strassen 11 单纯型算法 12 奇异值分解 13 求解线
  • upload-labs靶场第一关——第九关

    Pass 01JS检测绕过 1 根据提示 从上述代码中可以看出 上述代码使用了JavaScript脚本 在前端对用户上传文件的类型进行了检测 因此 我们只需要先上传符合JavaScript脚本要求的数据包 然后使用Burpsuit抓取该数据
  • python+Appium自动化:python多线程多并发启动appium服务

    Python启动Appium 服务 使用Dos命令或者bat批处理来手动启动appium服务 启动效率低下 如何将启动Appium服务也实现自动化呢 这里需要使用subprocess模块 该模块可以创建新的进程 并且连接到进程的输入 输出
  • 数据可视化第五章

    基于python的散点图实现 py import ggplot as gp import pandas as pd crime pd read csv crimeRatesByState2005 csv plot gp ggplot gp
  • 有点钱怎么做副业?应该投资哪些副业?

    有点钱怎么做副业 应该投资哪些副业 现在很多上班族 失业族 甚至连带孩子的妈妈们 他们不满足现状 给自己寻找赚钱的机会 一个是为了丰富自己的业余生活 再个就是能更加充实自己的钱包 让自己更为独立 也能自主 现在有哪些小途径可以实现轻松赚钱呢
  • Lua中的定时器

    Lua定时器 Cocos2d x C 中的定时器网上有很多 也很容易找 所以我就不写了 直接Lua吧 在Lua中用定时器的地方很多 我是深有体会啊 比如说我们需要一个函数每帧都执行 那么就可以用定时器来解决啦 旁白 好哇 好哇 终于可以解决
  • 搭建域控和添加本域辅域控,加入域(上)(精准扶小白)

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 安装环境 操作系统 Windows2012 一 什么是工作组 域 活动目录 树 林 工作组 处在同一个局域网中的用户 他们也默认处于同一个工作组 且加入工作组不需要信任过程
  • [PYTHON与CSP的姻缘]2023-3 LDAP

    练习过程 一开始一直以为set输出数字的时候是有序的 扣了一天一直显示错误 不知道哪跟哪 大冤种无语了 然后改了输出直接满分 无语ing 主要注意要考虑到表达式的一些嵌套 这样就可以参考题干中对语句的递归定义来写 用递归进行对表达式的切分处
  • react有哪些性能优化的手段?

    1 使用组件shouldComponentUpdate方法 通过在组件爱你中实现shouldComponentUpdate方法 可以手动控制组件的更新 在该方法中 可以根据组件的属性和状态进行比较 判断是否需要进行更新 避免不必要的更新可以
  • 539. Minimum Time Difference

    Given a list of 24 hour clock time points in Hour Minutes format find the minimum minutes difference between any two tim
  • 数据库几种删除的区别delete,truncate,drop

    delete from 表名 where 条件 gt 删除满足条件的记录 delete from test where id 1 delete from test gt 删除所有 commit gt 提交数据 rollback gt 回滚数
  • Java面试题大全(2021版)

    发现网上很多Java面试题都没有答案 所以花了很长时间搜集整理出来了这套Java面试题大全 希望对大家有帮助哈 本套Java面试题大全 全的不能再全 哈哈 博主已将以下这些面试题整理成了一个Java面试手册 是PDF版的 关注博主的微信公众
  • 用递归进行数组求和

    记录一下zj提前批算法一面 用递归进行数组求和 算法马上就写出来了 但是运行的时候一直报栈溢出 我以为是我的递归逻辑出问题了 就一直在改 但是还是报错 最终卡住了 开局就GG 自己也慌得一批 导致我第二道题也没做出来 最初写的代码如下 au
  • Nginx 负载均衡模块 ngx_http_upstream_module 详述

    译序 截至发稿时止 官方最新 ngx http upstream module 指令详述 官方随时在更新 请及时关注官网最新公布 以下是官方原文 ngx http upstream module 模块用于定义可以被 proxy pass f
  • GBase 8a 问题处理-集群管理节点无法正常启动

    问题版本 GBase 8a V8 6 2 43 R20 问题简述 在进行迁移工作的数据导入之后 启动集群所有管理节点一直不能正常启动 通过命令service gcware stop 也不能停止 报错信息 gcadmin 报错 Could n
  • MySQL索引优化(超详细)

    Mysql索引优化 1 索引介绍 1 1 什么时MySQL的索引 MySQL官方对于索引的定义 索引是帮助MySQL高效获取数据的数据结构 MySQL在存储数据之外 数据库系统中还维护着满足特定查找算法的数据结构 这些数据结构以某种引用 指