MySQL(五) 索引失效

MYSQL索引失效简介 索引失效可以简单理解为,在SQL语句执行时没有使用到索引列对数据库中的数据页进行查询。索引失效会导致查询性能显著下降,并可能引发一系列问题。 阅读详情

5. 表优化

1. (单表)索引优化案例一:

  • 建表操作:
CREATE TABLE IF NOT EXISTS `article`(
`id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`author_id` INT (10) UNSIGNED NOT NULL,
`category_id` INT(10) UNSIGNED NOT NULL , 
`views` INT(10) UNSIGNED NOT NULL , 
`comments` INT(10) UNSIGNED 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'),
(1,1,3,3,'3','3');
 
SELECT * FROM ARTICLE;
  • 查询category_id 为 1,且comment大于 1 的情况下,views 最多的 article_id
select id,author_id from article where category_id= 1 and comments>1 order by views desc limit 1;
  • explain 分析查询
explain select id,author_id from article where category_id= 1 and comments>1 order by views desc limit 1;

image-20200926182523102

我们不难发现一个问题,虽然只有3条数据,但是查询类型却是全表扫描(type=ALL),并且使用的是 Using filesort文件排序显示。 那么随着表的增大到百万级的数据量时,这将会大大增加数据库的负担。

即: type为All,即最坏的情况;Extra中也出现了 Using filesort,也是最坏的情况。

  • 查看索引情况
show index from article;

image-20200926183312609

  • 新建索引
create index idx_article_ccv on article (category_id,comments,views);

image-20200926183605101

  • 再次 explain 分析查询语句
explain select id,author_id from article where category_id= 1 and comments>1 order by views desc limit 1;

image-20200926183738909

通过 possible_keys 和 key, 我们不难发现这已经使用了 索引 idx_article_ccv, 但是查询类型也由All 改成了 range,提高了效率。 但是Extra 依然为 Using filesort。 这里的原因是 range范围查询 之后的字段 将不会使用索引,导致索引失效的问题。

  • 上述的并不是最优的建索引的做法,因此需要删除之前建的索引。
drop index idx_article_ccv on article;
image-20200926185008180

再次查询,检验索引已经删除了。

explain select id,author_id from article where category_id= 1 and comments>1 order by views desc limit 1;

image-20200926195253832

  • ​ 换个 建索引的做法:
create index idx_article_cv on article(category_id,views);

image-20200926202411399

  • 查看索引的结果
select index from article;

image-20200926205650561

  • explain 解析查询
explain select id,author_id from article where category_id= 1 and comments>1 order by views desc limit 1;

image-20200926205822201

我们可以发现现在的结果是我们能够接受的了。查询类型为ref,不再是All全表扫描。运用了索引,也不会出现 文本内存查询 。

总结:为什么第一次会出现索引失效的情况呢?原因是我们建立索引的时候是以 category、comments、views 的顺序建的 组合索引。又因为在SQL中的索引的底层是以 BTree 的方式建立的,那就要按照 B树 索引工作原理,先排序 category_id ,如果遇到相同的 category_id,则再排序comments,否则索引结束;如果遇到了comments,再排序views。 因为此时的 comments 字段在 联合索引 里处于 中间位置, 因此 comments>1 是一个范围值(即为 range),那么MySQL的 comments字段就失效,MySQL就无法利用索引再对 views 部分进行检索,即range类型查询字段后面的索引失效。

2. (两表)索引优化案例二:

  • 建表操作:
CREATE TABLE IF NOT EXISTS `class`(
`id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`card` INT (10) UNSIGNED NOT NULL
);
CREATE TABLE IF NOT EXISTS `book`(
`bookid` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`card` INT (10) UNSIGNED NOT NULL
);
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 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)));
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)));
  • 查询 class 和 book 存在关联的结果
select * from class left join book on class.card=book.card;
image-20200926211557444
  • expalin 分析 查询语句
explain select * from class left join book on class.card=book.card;

image-20200926211734277

因为我们两个表的card字段都没有进行加索引,因此两张表都进行全表扫描。

  • 创建为book表创建索引
create index idx_card_book on book(card);
  • 查看索引,并用explain分析查询语句
explain select * from class left join book on class.card=book.card

image-20200926212753753

  • 当只在 left join 中的 右表建立索引, 那么执行的查询类型为 ref,此时的执行效率较高。

image-20200926222032464

  • 当只在left join 中的 左表建立索引,那么执行 查询类型为 index, 效率较低。但优于All;

image-20200926221529235

  • 总结:

    左连接的特性是,左边表一定会进行全表扫描,那么不管左边是否建立索引都会全表扫描。所以关键是在右表上,确定右表是如何进行扫描,所以一定要建立索引优化。

3. (三表)索引优化案例三:

  • 建表
CREATE TABLE IF NOT EXISTS `phone`(
`phoneid` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`card` INT (10) UNSIGNED NOT NULL
)ENGINE = INNODB;

INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
INSERT INTO phone(card)VALUES(FLOOR(1+(RAND()*20)));
  • 查询表

  • 查看 index 索引 情况

image-20200926230824577

  • 查询 三表连接
 select * from class left join book on class.card = book.card left join phone on  class.card = phone.card;
  • explain 分析 三表连接查询
explain select * from class left join book on class.card = book.card left join phone on  class.card = phone.card;

image-20200926231417498

我们不难发现,此时三张表都是全表查询。Extra额外信息是有 Using join buffer, 即使用了连接缓存。

  • 建索引时(驱动表class)

image-20200926235106670

此时只用到了 查询类型为index,且查询的条数为20条,效率低。

  • 建索引时(被驱动表 book)

image-20200926235428041

此时在两个驱动表中就存在这区别了,因为book表中对card字段建立了索引,所以查询类型为 ref,额外信息Extra 中的使用的时Using index,查询行数为1,效率明显高于未建索引时。

  • 建索引时(被驱动表book 和 被驱动表 phone)

image-20200926235734403

此时总查询的行为 22行,相比于未建索引的效率大大提升。

4. 上述总结:

  • join语句的优化时,尽可能减少join语句的 NestedLoop 的循环次数;
  • ==永远使用小结果集驱动大结果集的方式进行。==left join 的左表为驱动表,右表为被驱动表。
  • 保证 join 语句中的被驱动表上 join 条件字段已经被索引。
  • 在无法保证被驱动表的 join 条件字段被索引,且内存资源充裕的情况下,不要吝惜 JoinBuffer 的设置。

6. 索引失效

1. 最左前缀法则

  • 建表
CREATE TABLE staffs(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(24)NOT NULL DEFAULT'' COMMENT'姓名',
`age` INT NOT NULL DEFAULT 0 COMMENT'年龄',
`pos` VARCHAR(20) NOT NULL DEFAULT'' COMMENT'职位',
`add_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'入职时间'
)CHARSET utf8 COMMENT'员工记录表';
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('z3',22,'manager',NOW());
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('July',23,'dev',NOW());
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('2000',23,'dev',NOW());

create index idx_staffs_nameAgePos on staffs(`name`,`age`,`pos`);
# ALTER TABLE staffs ADD INDEX index_staffs_nameAgePos(`name`,`age`,`pos`);
  • 查看索引
show index from staffs;

image-20200927001436354

  • 查询语句
select * from staffs;

image-20200927001821369

  1. explain 分析 name=‘July’;
explain select * from staffs where name = 'July';

image-20200927001957500

  1. explain 分析 name=‘July’ and age=23 ;
explain select * from staffs where name='July' and age=23 ;

image-20200927002244256

  1. explain 分析 name=‘July’ and age=23 and pos=‘dev’;
explain select * from staffs where name='July' and age=23 and pos='dev';

image-20200927002204739

  1. explain 分析 name=‘July’ and pos=‘dev’ and age=23;
explain select * from staffs where name='July' and pos='dev' and age =23;

image-20200927002926494

  1. explain 分析 name=‘July’ and age=23;
explain select * from staffs where name='July'  and pos='dev' ;

image-20200927003634118

  1. explain 分析 pos=‘dev’
explain select * from staffs where pos='dev' ;

image-20200927003708111

  1. explain 分析 age=23;
explain select * from staffs where  age =23;

image-20200927004656181

分析:
  • 通过示例 ①,②,③: 我们可以发现使用的索引个数为1,2,3个,且key_len 长度不断增加。
  1. 通过示例 ③,④:我们可以发现当查询的索引都被使用时,即为 idx_staffs_nameAgePos 中的三个索引字段都使用, 此时与where 出现的字段的先后顺序无关。
  2. 通过示例⑤,我们可以发现使用的字段为组合索引中的前后两个字段,没有使用中间字段时,即使用了name和Pos,此时的Pos已经失效,无法应用上。可用过示例①的key_len的长度等于示例⑤的长度论证。
  3. 示例⑥、⑦: 当直接使用组合索引中的后面字段时,索引将会失效。
总结:

最左前缀法则:如果索引了多列字段,要遵循最左前缀法则。指的是查询从索引的最左前列开始并且 不跳过索引中的列。

2.不在索引列上做任何操作(计算、函数、类型转换)

首先上例子,一个是使用了函数,一个没有使用函数的查询语句;

mysql>  select * from staffs where name='July';
 
mysql> select * from staffs where left(name,4)='July';

image-20201118194846727

通过结果,我们很容易的发现,这两条语句的查询结果是一样的。因为 left() 函数需要传入两个参数,第一个参数为查询的字段,第二个参数为截取长度。 left(name,4) 意思就是对name字段的结果进行截取,并返回至多4个字符。

那么接下来再用 explain 进行分析这两条语句的区别:

image-20201118195445021

我们可以发现,在使用了函数之后,索引就已经失效了。

3. like 以通配符开头(%abc…)

当MySQL表中如果对某个字段建立了索引,但由于查询是使用了 like,进行匹配。如果使用通配符%开头的话,将会导致索引失效,从索引扫描变成全表扫描。

image-20201118203314294

有百分百和没百分号查询的结果相同。

查看explain 分析的结果:

image-20201118203529538

我们不难的发现,以 通配符%开头的话,key字段为NULL,说明没有使用上索引。

结论:只在右边使用 通配符% 的效率最高,通配符开头会导致索引失效问题

  • 导致问题:如果实际开发项目中,一定要使用通配符%开头,但又会导致索引失效,该问题是如何解决的呢?

  • 对于通配符导致索引失效的问题,我们通常使用覆盖索引的方式进行解决,即我们为需要查询的字段建立覆盖索引。

    • 查看 表staffs 的表结构

      image-20201118210632664

      假如我们需要对 name字段继续模糊匹配,并经常性的需要返回name,age,pos字段的话,我们可以对 name,age,pos三个字段建立一个覆盖索引

      create index idx_staffs_nameAgePos on staffs(name,age,pos)

      image-20201118210917063

      此时如果使用通配符查询时,不会导致索引失效。但这还是有前提的哦。。。。。

      image-20201118211055894

      我们不难发现,该方式进行查询时,通配符没有导致索引失效。

  • 但者不是意味着不会出现索引失效

    • 当我们查询的是所有字段 * 或者是 不包含在覆盖索引中的字段时,依然会导致索引失效哦

    • mysql> explain select name,age,pos,add_time from staffs where name like "%J%";
      
      mysql> explain select * from staffs where name like "%J%";
      
    • image-20201118211408396

    • 所以这两种情况最终还是导致索引失效了。

  • 总结:在使用通配符时,我们一定要清楚什么时候会导致索引失效,哪些字段才是我们最常用的字段。

4. 字符串不加单引号,会导致索引失效

​ 我们都知道 如果是字符串类型的话必须加引号,至于数值类型的可加可不加。 但是字符串类型是纯数字的话,不加引号也是能查询到结果的。

例1: select * from staffs

image-20201119092101356

从这张表中,我们可以看到第三条记录得 name 为纯数字。

mysql> select id,name,pos,add_time from staffs where name=2000;

mysql> select id,name,pos,add_time from staffs where name='2000';

image-20201119092258332

通过结果,我们可以发现 对于纯数字是可以不加单引号也能的结果的。


  • 但这就代表没有问题了吗?

其实不然,我们用explain 进行分析一下:

image-20201119092602958

在上图中,我们可以看出如果对字符串类型加了单引号的话,是可以使用到覆盖索引的,但是如果没加单引号,则不会使用。其实这也验证了第二条语句,自动类型转换会导致类型失效。MySQL底层自动的将整数类型转换成了字符串类型。

5. 应当少用or语句,or语句会导致索引失效

网上经常能看到一些文章总结在 mysql 中不能命中索引的各种情况,其中有一种说法就是指使用了 or 的语句都不能命中索引。

这种说法其实是不够正确的,正确的结论应该是,从 mysql5.0 后,如果在 or 连接的字段上都有独立的索引的话,是可以命中索引的,这里就是用到了 index_merge 特性。

举个栗子⚽:

image-20201119103726270

在数据库表staffs中,只有 一个 name,age,pos字段的组合索引(覆盖索引)。

mysql> select * from staffs ;

mysql> select * from staffs where name='July' or age=23;

mysql> select * from staffs where name='July' or name='2000';

image-20201119104120204

说明都能查询到数据,但这两种方式继续explain分析以下结果,看看是不是使用了or就不能使用索引了呢?

mysql> explain select * from staffs where name='July' or name='2000';

mysql> explain select * from staffs where name='July' or age=23;

image-20201119104418821

😭很出乎意料啦,查询条件只有name字段的话,还是会使用上索引的,所以,上述说法并不完全正确。

  • 那问题来了:如果我们业务需求一定要用name 或者 age进行筛选,那怎么办呢?

  • 这样的话我们依然只能够使用**组合索引(覆盖索引)**的方式,将并且显示列出需要查询的字段,而不是使用 *。

  • explain select name,age from staffs where name='July' or age=23 ;
    

    image-20201119111514661


6. order by ,group by 导致索引失效(难点)

在使用索引的时候,我们理想情况下是将 Extra 信息未NULL。当然啦,如果在使用文件排序有可能会出现Using filesort,出现这个的话,会影响系统的查询效率,应该适当优化。那就来举几个栗子,看看什么时候会出现吧。

**特别强调:**索引的主要功能就是==查询和排序==

🐷栗子1: 查询的是 * 的情况

我们依然用 staffs 表进行举栗子哈

# 查询语句1
mysql> explain select * from staffs where name='July' order by name;
# 查询语句2
mysql> explain select * from staffs where name='July' order by age;
# 查询语句3
mysql> explain select * from staffs where name='July' order by pos;
# 查询语句4
mysql> explain select * from staffs where name='July' order by age,pos;

image-20201119140849299

通过上面例子,我们可以发现四个查询语句都是使用了索引中的第一个字段的,也就是说查询语句只用到了一个字段进行查询;

再拿 栗2、栗3做对比的话,我们可以发现例三是出现了文件内排序(Using filesort)的,也就是说索引并没有使用上,导致索引失效了。而栗四就是用上了索引中的排序功能,虽然查询只用到了一个字段。但整体效率还是不错的。


🐷栗2:

# 查询语句5
mysql> explain select * from staffs where name='July'  order by name;
# 查询语句6
mysql> explain select * from staffs order by name;
# 查询语句7
mysql> explain select name from staffs order by name;

分析语句:

没有对比就没有伤害,这一组的分析,得运用上SQL语句的执行顺序。

  • 在查询5的语句中,使用了where name=‘July’,那么就会用上索引结构,因此不会出现文件内排序;
  • 而查询6的语句是没有使用where,并且是 select *,经过之前的栗子,我们知道select * 是不会使用索引的,所以这次order by 会出现 文件内排序。
  • 而查询7的语句虽然没有使用where,但是select name, 因此是会使用索引的,进而使用上了索引排序,而不是文件内排序。

image-20201119142722086


🐷栗3:

# 查询语句8
mysql> explain select name,age,pos  from staffs  ;
# 查询语句9
mysql> explain select name,age,pos  from staffs order by name  ;
# 查询语句10
mysql> explain select name,age,pos  from staffs order by age;
# 查询语句11
mysql> explain select name,age,pos  from staffs where name='July';
# 查询语句12
mysql> explain select name,age,pos  from staffs where name='July' order by name;
# 查询语句13
mysql> explain select name,age,pos  from staffs where name='July' order by age;
# 查询语句14
mysql> explain select name,age,pos  from staffs where name='July' order by pos;

分析语句:

这再次强调了索引的作用了,索引就是优化查询和排序。在建索引时,已经订好了顺序了。

  • 通过查询10 的语句,我们可以发现,如果没有name,那么就不会使用上索引的排序,那么就会将查询到的结果放入内存中,再进行排序。
  • 同理啦,查询语句14,也是一样的,首先加载了name的字段,但是对于查询pos来说,是乱序的,所以只能将查询的结果也加载到内存中啦。

image-20201119145039895


🐷栗4:

# 查询语句15
mysql> explain select name,age,pos  from staffs where name='July' order by age;
# 查询语句16
mysql> explain select name,age,pos  from staffs where name='July' order by age,name;
# 查询语句17
mysql> explain select name,age,pos  from staffs  order by age,name;
# 查询语句18
mysql> explain select name,age,pos  from staffs;

分析语句:

  • 查询语句15,16都有使用上了 where name='July',因此是先查询了所有结果为name=‘July’ 的记录项。对于查询语句16来说,此时 虽然是order by age,name.但因为name已经是一个常量了,那么这里的order by 等价于是 order by age,name=const 。而索引建立时就是以name,age排序的,所以最终对于age来说是有序的。
  • 查询语句16对比17,区别就是 索引树中先排序的是name,再排age,但是我不使用。我要强行排age,再来排name,这就必然会文件内排序啦。

image-20201119150854390

索引总结:

其实我们可以以一种很形象的形式理解什么是组合索引。

举个例子,我会把组合索引比喻成一栋酒店,那么组合索引的第一个字段,我们可以理解成一层层楼,而第二个字段比喻成一个个房间,第三个字段当然就是房间的物品了。。。。以此类推下去

那如果我们出去住酒店,拿到房间号是4-12,我们很容易就能理解,我们的房间在4楼的12号房间啦,那我们想要回到自己的房间,很自然的就直接去4楼,而不会一层一层的去看下这个是不是我们的房间。

如果一天老板说,张三,你去把房间号排下序,顺序按这个条件排下order by(字段2,字段1),张三此时心里肯定是妈卖批的啦😭。老子都拍好字段1,字段2了,你不用,却要反着来。我也不知道每一层的房间号数量是不是一致的啊。

最终张三只能很苦逼的拿着这些房卡进行再次排序。

这就是组合索引啦,很多情况以这个想法,变位想想,就很清楚啦。

MySQL索引失效的场景 表中的某些列可能会存储 NULL 值,如果把这些 NULL 值都放到记录的真实数据中会比较浪费空间,所以 Compact 行格式把这些值为 NULL 的列存储到 NULL值列表中。如果存在允许 NULL 值的列,则每个列对应一个二进制位(bit),二进制位按照列的顺序逆序排列。二进制位的值为1时,代表该列的值为NULL。二进制位的值为0时,代表该列的值不为NULL。另外,NULL 值列表必须用整数个字节的位表示(1字节8位),如果使用的二进制位个数不足整数个字节,则在字节的高位补 0。 阅读详情

相关推荐

SCU【C】程序设计基础期末安全项目lab2-Deadbeef-writeup(附题目&源码)

项目名称(本质:栈溢出攻击)【源码在文首】和lab1一样,此题又是美国卡耐基梅隆大学的平时作业哈哈哈! 项目要求是把栈溢出,强行更改函数返回值,输出0xdeadbeef。

2301_79586491的博客 1544

查询索引range失效

在某一个时间字段加索引,短的时间范围内查询,索引生效,为range。长时间范围,索引失效,查全表。 当索引查的数据量超过全表30%的数据,索引失效,会查全表。 转载于:https://www.cnblogs.com/tonggc1668/p/7596768.html...

weixin_30741653的博客 760

关于石墨烯费米能级和偏置电压之间的关系问题

石墨烯费米能级与电压的关系问题

qq_37946542的博客 3514

如何解决mysql错误 Out of range value for column ‘xxx‘ at row 1呢?

这个错误,从字面意思来看是我们要放的值超过了长度,所以才会报这个错误,我遇到这个错误好几次都是在线上遇到的。刚开始一直很纳闷,因为自己查看还没有大到超过我设定的长度,这里我默认超过长度一定是因为 太大了, 其实也有可能是太小了,比如我这几次遇到的。就是因为数据库设定的是bigint,但是实际业务在流传中,导致赋予的值变成了负数,也就是把一个负数赋值给一个bigint类型的字段,所以报的这个错误。 ...

独狼的博客 1万+

从OpenClaw到Hermes Agent:AI Agent实战部署与自动化工作流构建

AI Agent(智能体)作为大语言模型(LLM)的能力延伸,其核心原理在于通过工具调用(Tool Calling)与环境交互,使模型从“对话”走向“执行”。这一技术价值在于将自然语言指令转化为具体操作,实现业务流程自动化,从而提升开发与运维效率。在应用场景上,AI Agent广泛适用于自动化运维、智能客服、数据报告生成等重复性任务处理。本文聚焦于两大热门开源框架OpenClaw与Hermes Agent,深入探讨其部署配置、技能扩展及实战联调。通过结合OpenClaw的模块化扩展能力与Hermes Age

weixin_34122810的博客 506

GPL vs MIT:独立开发者选择开源协议的法律与商业考量

你可能听过这样的故事:某个开发者用业余时间写了个超好用的工具库,开源后被某大厂悄悄集成到闭源产品里赚得盆满钵满,开发者却连杯奶茶钱都没拿到;也可能听说过另一个案例:开发者选了GPL协议,结果用户修改代码后必须开源,反而推动项目社区快速壮大,最终靠技术服务赚到了钱。这些故事的核心矛盾,都源于开源协议的选择。对于独立开发者(尤其是单枪匹马写代码的个人或小团队),开源协议不是“随便选一个就行”的小事——它是代码的“使用说明书”,更是保护自身权益、规划项目未来的关键工具。

AI天才研究院 1180

mysql数据库插入数据时出现 1264 Out of range value for column 错误的解决办法

mysql数据库插入数据时出现 1264 Out of range value for column 错误的解决办法分析原因解决方法 分析原因 新版本的MySQL对字段的严格检查。 通常在Linux下安装完mysql后,默认的sql_mode值是空,在这种情形下mysql执行的是一种不严格的检查,如果要插入的字段长度超过列定义的长度,那么mysql不会终止操作,而是会自动截断后面的字符继续插入操作...

徊忆羽菲 5963

camera 知识速查

本文总结了Camera开发中的常见问题排查方法和关键技术点。主要内容包括:I2C/MIPI不通的排查步骤、时序问题分析方法、Sensor/AF/Flash/PDAF的Bring Up流程、OTP调试方法、PDAF原理及调试、CTS/ITS问题解决思路、AE震荡解决方案、Systrace性能分析方法、Flicker产生原理、Tombstone问题定位等。还涉及V4L2框架解析、问题定位分层方法、Sensor Setting注意事项、时钟信号概念、第三方应用卡顿排查、大光圈概念、Monkey测试方法。

qq_41665131的博客 784

索引失效的情况及解决(超详细)

mysql索引优化

sy_white的博客 8万+

23种设计模式-代理(Proxy)设计模式

软考中级-软件设计师 代理设计模式

片言可决讼,半纸能缚龙 1784

支付域——“清算、结算、清结算”

本文深入探讨了支付系统中的清算和结算流程,包括核心流程、模块设计及特殊场景处理。文章详细阐述了交易收单、资金冻结、清分规则、清算批处理、结算出账等关键步骤,并讨论了交易失败、数据不一致、退款、汇率波动等异常情况的处理方法。

庄小焱 2564

MySQL高级篇——索引失效的11种情况

索引优化思路、要尽量满足全值匹配、最佳左前缀法则、主键插入顺序尽量自增、计算、函数导致索引失效、类型转换(手动或自动)导致索引失效、范围条件右边的列索引失效、不等于符号导致索引失效、is not null、not like无法使用索引、左模糊查询导致索引失效、“OR”前后存在非索引列,导致索引失效、不同字符集导致索引失败,建议utf8mb4

种一棵树最好的时间是十年前,其次是现在 3万+

动画实例化:千人同屏不卡顿的秘密

是一种将大量相同骨骼结构的角色动画批量处理、批量渲染的技术。动画计算与渲染解耦,动画数据在CPU或GPU上批量计算,渲染时通过GPU Instancing一次性绘制大量角色。极大减少DrawCall,提升大规模角色(如MMO、RTS、群体AI等)动画的运行效率。动画Bake:编辑器下将所有动画片段Bake为骨骼矩阵纹理。实例参数管理:每个角色维护自己的动画状态、帧索引等。批量渲染:用DrawMeshInstancedIndirect等API批量渲染,Shader中采样骨骼数据。剔除与LOD。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 421

【MySQL高级】(五)索引失效、索引优化

1. 前言   索引的建立是为了让我们更加高效快速的查询出结果,但是,要想充分利用起索引,我们首先要解决的最大问题就是要避免索引失效,下面我们来一起通过实例来探讨造成索引失效的情况,并通过优化SQL查询语句来避免索引失效。 ➤ 准备工作:、 创建数据表SQL CREATE TABLE `staffs` ( `id` int(11) NOT NULL AUTO_INCREMENT COM...

JinXYan的博客 870

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

mysql高级(五)索引失效

1.索引失效 1.全值匹配 如果不按照顺序来索引失效 综合上述的例子规则 火车头不能少 中间兄弟不能断 如果有开头中间断就会用到部分索引 以上只用到name索引 综合上面例子结论:带头大哥不能死 中间兄弟不能断 范围后全失效,age索引用到是一个范围索引 可以采用输出字段与条件一样的字段,再在这个字段上创建索引 ...

lovezhaohaimig的博客 325

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

mysql length 失效_mysql学习(五)避免索引失效的一些原则

避免索引失效的原则1.复合索引a.复合索引,不要跨列使用或无序使用(遵循最佳左前缀)b.复合索引尽量使用全索引匹配2.不要在索引上进行任何操作(计算、函数、类型转换),否则索引失效select ..where A.x = .. ; --假设A.x是索引不要:select ..where A.x*3 = .. ;explain select * from book where authorid =...

weixin_28947385的博客 648

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

mysql 性能优化(五)避免索引失效原则及常见优化方法

sql优化是一种概率层面的优化,不是百分百的,至于是否使用了我们的优化,需要通过explain进行推测 因sql优化器可能会进行修改执行的sql in可能导致失效 不要在索引上进行任何操作(计算,函数,类型转换等 ),否则索引失效 复合索引 复合索引满足最佳左前缀,不要跨列和无序使用,如果左侧失效,则右侧全部失效。 尽量使用全索引匹配 例如x是一个表的索引 :select …where x*3 = 6;这样会导致索引失效 不能使用!=、<>、 is null、is not null,否则

CodingAnHour 1614

mysql 高级(基础五 索引优化(索引失效))

建表sql: create table staffs( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(24) NOT NULL DEFAULT '' COMMENT '姓名', age INT NOT NULL DEFAULT 0 COMMENT '年龄', pos VARCHAR(20) NOT NULL DEFAULT '' COMMENT...

Mic_star的博客 441

MySQL中什么情况下会出现索引失效?如何排查索引失效?

在MySQL中,索引是用来加快检索数据库记录的一种数据结构。索引失效指的是在进行查询操作时,本应该使用索引来提升查询效率的场景下,数据库没有利用索引,而是采用了全表扫描的方式,这会大大增加查询时间和系统负担。MySQL中什么情况下会出现索引失效?如何排查索引失效?回答。

weixin_44382896的博客 8202

mysql索引失效的常见9种原因详解

目录 前言: 1.最佳左前缀法则 2.主键插入顺序 3.计算、函数、类型转换(自动或手动)导致索引失效 4.范围条件右边的列索引失效 5.不等于(!= 或者<>)导致索引失效 6.is null可以使用索引,is not null无法使用索引 7.like以通配符%开头索引失效 8.OR 前后只要存在非索引的列,都会导致索引失效 9.数据库和表的字符集统一使用utf8mb4 特别鸣谢: 前言: MySQL中提高性能的一个最有效的方式是对数据表设计合...

qq_63815371的博客 3万+

MySQL之索引失效情况

文章目录1 MySQL索引1.1 简介1.1.1 索引创建1.1.2 索引类型1.1.3 索引优缺点1.2 SQL优化1.2.1 查看执行计划1.2.2 show profile分析1.2.3 trace2 索引失效2.1 问题引入2.2 准备工作2.2.1 创建user表2.2.2 插入数据2.2.3 查看数据库版本2.3 联合索引2.3.1 联合索引中索引有效2.3.2 联合索引中索引失效2.4 select *2.5 索引列上有计算2.6 索引列用了函数2.7 字段类型不同2.8 like左边包含%2

上善若泪 8823

Mysql索引失效

在数据库日常使用中,因索引失效而导致的没有充分利用索引,是导致数据库查询效率低下的一个重要原因之一。 本文介绍索引失效的十一种情况。

m0_62946761的博客 9936

mysql索引失效

在MySQL中,索引失效指的是查询语句无法有效地使用索引,而必须进行全表扫描。索引失效可能会导致查询性能下降,特别是在处理大量数据时。

liulanba的博客 2192

MySQL索引失效的12种场景及解决方案

索引优化是一个持续的过程,需要结合具体的业务场景和数据特点。通过了解这些索引失效的场景和原理,你可以更有针对性地设计索引策略,显著提升数据库性能。没有一劳永逸的索引方案,随着数据量的增长和业务的变化,索引策略也需要不断调整和优化。持续监控、分析和优化是保持高性能数据库的关键。

风象南的专栏 4122
上一篇: MySQL(四) Explain分析器
下一篇: MySQL 数据库锁理论(六)
Dim_Jerry
博客等级 码龄8年 14粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值