在新部署的TiDB-v8.1.0 集群中导入了几张大表,发现做关联查询时候非常慢,analyze后毫秒级,之前要十几分钟

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面
【附件:截图/日志/监控】

SELECT pn.id FROM p_news_c pn LEFT JOIN p_news_s pns ON pn.id = pns.id WHERE pn.newsType = 3 AND createTime >= ‘2024-07-10 12:04:24’ AND ( pns.sourceType = 0 OR pns.sourceType IS NULL ) ORDER BY pn.id) DESC LIMIT 1;

2张表都是2亿2千多万。导入后搁置了几天。查询条件的createTime如果调整为早一些(有数据),那么查询很快,而如果createTime对应的范围没有记录,那么查询非常慢。

在7.6版本也做了同样的操作,结果一样,并且对表做了部分更新,但是结果一样都是需要analyze表才行。

analyze之前的执行计划还有没有,是不是索引没有起作用

新导入的表,执行计划同上,但是如果createTime取值范围不同,执行计划是一样的,但执行的速度差异却非常大,有数据返回的需要毫秒,无数据返回的10多分钟,这些都是在没有执行analyze时候的状态

刚才写反了,是有数据的快,无数据的慢

走索引了吗

从执行计划看没有走索引。
不过createTime取值不同情况下,执行计划是一样的,就是执行时间差异太大,有数据返回的很快,无数据返回的很慢。

有数据的就是命中数据了,反而快一些,没有命中的继续全表扫描,需要扫描整个表的数据

看执行计划是全表扫描了

使用analyze命令之前,查看下sql语句的执行效率,对比下各自的执行计划,看看有无差别。另外,使用该命令会将表的真实统计量反馈到pd调度中心,然后内部优化器会根据sql情况自行选择对应的优化查询,如果pd中的统计信息不准确,会影响优化器的判断和执行

你用时间字段查询的话,统计信息必须很新才行,否则执行计划很容易走错,同时显示也不准确。

这么说凡是新导入的表都需要手工发起收集统计信息,否则就会因为统计信息不正确影响查询。另外还有一个问题,我导入后是过了几天才测试语句的,为什么这几天系统都没有自动收集统计信息,我部署集群并没有调整过配置,都是按缺省配置。

mysql.analyze_jobs 找下这个表有没有收集过统计信息

limit去掉做比较吧

目前是空表。手工发起后会有记录,过一段时间后表就自动清空了。

1、因为你带limit了,有数据的情况找到1条直接返回会很快,如果是空哪要扫描所有数据后才知道没有数据所以慢
2、 统计信息问题可以看下这个:专栏 - TiDB 优化之消失的统计信息 | TiDB 社区

虽然是有Limit 1,但是要先进行倒排序,理论上也应该扫描完所有记录

id是主键吗

是的。另外我看了统计信息这篇文章。


如上图,红框就是2张关联查询的表,Healthy都很高。STATS_HISTOGRAMS和STAS_META都有数据。而且对比另外一套环境(做了analyze)数据相似


是主键看执行计划tikv就是有序返回的,慢也的对的上 :grinning:

不是这样的,理论上导入的表集群会统计相关信息,只不过频繁的操作表过程中,如果集群没来得及更新相关信息才会导致统计不准确

我导入数据后是过了几天才进行的查询测试,这才发现查询异常,然后进行analyze操作。另外我新部署了一套7.5环境,同样导入数据后也出现一样的问题。所以怀疑是不是大数量的导入统计信息实际上是不准确的或者说统计信息需要等待较长的一段时间后才会逐步更新。按说 tidb_auto_analyze_ratio 的默认值为 0.5,而且进过几天时间,理论上应该会有自动收集。