TiDB是否包含伪造统计信息的功能

TiDB的定位是可扩展的分布式数据库,生产上会有数十亿上百亿的表。
有时候出现新需求或者问题SQL时,仅靠已有统计信息只能大致推测新增索引的效果,但不足以100%的确认。
我印象中Oracle有这种伪造统计信息以供优化器使用的能力(记不太清了),不知道tidb是否有计划加入此特性或当前是否有此功能?

tidb本身就是这个逻辑啊,统计信息过时,使用伪随机数生成器(pseudo-random number generator)来估算统计信息,用来生成执行计划
而oracle的统计信息我记得只有在统计信息为空的情况下,才会动态估算统计信息然后生成执行计划,只要有统计信息,就会根据统计信息来生成执行计划
如果想伪造,只能将一张列和索引信息一模一样的表的统计信息导出,然后导入到当前表中,才可以出现伪造的效果

1 个赞

既然统计信息能导入导出,那应该也可以直接修改导出的json文件再导入来伪造
https://docs.pingcap.com/zh/tidb/stable/statistics#导入统计信息

1 个赞

你这么一提,我突然发现我的表述可能是错的,我想的是伪造索引,然后根据新索引进行执行计划查询。

嗯嗯 我想我要的功能是模拟给表新建索引并生成虚拟的统计信息,然后据此观察SQL优化器的反应

你是指这个么?

1 个赞

感觉就是一个问题的正反面。

新建一个假的索引在真的统计信息上看执行计划。
或者新建一个真的索引在假的统计信息上看执行计划。

我没试过这个文档的内容,我是不太确定后者能否实现。
如果后者能做到的话,这两者的代价是差不多的。
在空表上建真索引,给假统计信息就行了。

1 个赞

类似如此,我大致描述下使用场景:
我有一个数十亿的表,现在发现有一个SQL执行会导致IO打满,因此在查看了相关列的histogram和buckets统计信息后决定加一个索引,我可以大致推测出这个索引可能会起到效果,但是我无法100%预测SQL优化器面对此索引的反应,如果我最终耗费时间建好了索引却发现未如预期那样生效,那就做了很多无用功。
我理想中的处理手段:
创建一个虚拟索引,并为此虚拟索引收集统计信息(自动or手动皆可,甚至可以导入),然后观察优化器对此的反应。

:disguised_face:你说的真的是一个很巧妙的办法,可以新建表并导入统计信息!
如果能有内置的虚拟索引并自动生成统计信息的功能那就太好了。

我感觉不用那么复杂,建个一模一样的表,导原表的1%的数据进去,然后新建你想建的这个索引,看看原来同样的sql是否会有效果,有的话,就在原表上也建上这个索引即可。

2 个赞

我按着文档做了下,可以的。

导出json文件以后,把json文件里面的

 "database_name": "test",
 "table_name": "t",

这两个字段指向假的空表。

再load stat 这个json文件就行了。
可能还需要lock stat 一下。
我没有先锁定,建立了新的索引后,统计信息变了,然后不得不又重新load stat了一次。

之后,可以看到执行计划是否用到索引。
操作是不如虚拟索引方便。不过效果是能差不多的。

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。