mysql数据库查询不到表

mysql数据库查询不到表,第1张

1.查看数据库,选中使用数据库,并查看数据库表,具体 *** 作命令如下:

show databases

use student

show tables

2.选择student数据库中的一张表stu_score,查看数据库表数据,并利用explain分析数据库表,如下图所示:

select * from stu_score

explain select * from stu_score

3.查看数据库使用索引的情况,使用命令:

show status like 'Handler_read%'

4.用于分析和存储表的关键字,分析的结果可以得到精准的信息,利用命令analyze,

analyze table stu_score

5.检查数据库表stu_score,检查表是否有错误,利用命令:

check table stu_score

6.优化数据库表,利用命令:

optimize table stu_score

官方版本测试到8.0.21依旧存在这个问题,Percona已经修复了,修复如下

https://www.percona.com/blog/2018/03/27/analyze-table-is-no-longer-a-blocking-operation/

能力有限简单记录。

问题如下:

乍一看来,很是奇怪,这里没有出现我们经常遇到的flush table/flush table with read lock 堵塞,直接出现了 Waiting for table flush的堵塞,有点像

https://www.jianshu.com/p/b141585cd844

以前记录的文章中的案例2,但是其实并不一样,这里是由于analyze table语句造成的。构造非常简单(必须是社区版本,我使用的8.0.21),如下:

此时堵塞的情形就是Waiting for table flush

analyze table 除了更新我们的统计数据,实际上最后做了一个 *** 作如下(栈):

大概看一下做了什么,如下:

这里判断了是否当前table share正在使用,如果正在使用(很显然我们这个table share是不能直接释放的,因为有select一直持有它)那么将share版本的设置为0(share->clear_version(),实际上这个版本由全局变量refresh_version初始化),目的在于下次如果有使用表定义的时候需要重新打开table share。然后释放了当前没有使用的table cache(类型TDC_RT_REMOVE_UNUSED),如下:

当再次访问表的时候(open_table),会去判断如下是否有老的table share存在,如果存在则需要等待释放:

首先如果存在判断是否存在的老版本,判断是通过table share的版本和当前全局版本refresh_version进行比对,前面我们知道这里table share的版本已经设置为0,因此这里必然进入release_table_share环节,然后等待持有者的释放(案例窗口1的select查询),然后再次获取table share。等待栈如下:

进入waiting for table flush状态

Percona在上文中已经提到问题如下:

一个关键的修改点如下

官方版本:

Percona版本:

如此修改后analyze不会进入tdc_remove_table函数,那么table share的版本不会设置为0。因此如果使用官方版本小心本问题。

该命令有助于诊断性能低下的查询,尤其是查询是否使用了可用的索引。下面介绍下 这个命令显示的结果列的含义:

| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |

1️⃣Table:索引所在的表名

2️⃣Non_unique:0表示该索引是唯一索引,1表示该索引不是唯一索引

3️⃣Key_name:索引的名称

4️⃣Seq_in_index:索引列在索引中的位置,从1开始。对于组合索引来说,这个字段很重要。

5️⃣Column_name:索引列的名称

6️⃣Collation:索引列的值以什么方式存储在索引中。在MySQL中,A 表示有排序,B+树索引使用该方式;NULL 表示无序的,Heap索引使用该方式;

7️⃣Cardinality:索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。 索引列所有值去重后的数量。该值除以该表的行数越接近1越好,如果非常小,则需要考虑是否可以删除该索引!

8️⃣Sub_part:数值 N 表示只对该列的前 N 个字符进行索引;NULL 表示索引整个列的值

9️⃣Packed:指示关键字是否被压缩,NULL 表示没有压缩

1️⃣0️⃣Null:索引列是否可以为空

1️⃣1️⃣Index_type:索引类型,BTREE 表示B+树索引。一共有四种(BTREE, FULLTEXT, HASH, RTREE)。

1️⃣2️⃣Comment:注释

1️⃣3️⃣Index_comment:注释

本语句用于分析和存储表的关键字分布。在分析期间,使用一个读取锁定对表进行锁定。这对于MyISAM、BDB和InnoDB表有作用。对于MyISAM表,本语句与使用 myisamchk -a 相当。

MySQL使用已存储的关键字分布来决定,当对除常数以外的对象执行联合时,表按什么顺序进行联合。本语句会返回一个含有以下列的表:

当需要删除一个索引时,使用语句:

需要特别注意的是,当使用组合索引时,where 语句中最常使用的字段名,应该放在组合索引中的第一个。比如,以下组合索引的定义:

基本就可以判断,id,book,author 作为 where 的查询条件的频率,从大到小应该是:id >book >author。还需要知道的一点是,触发组合索引的条件是向后匹配组合索引中的字段。还是看上面这个组合索引的例子,当查询语句的 where 条件包括下面任何一种情况,才会触发组合索引:

如果是以下任何一种情况,则不会触发组合索引:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7256417.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存