表亿级数据,查询速度慢

【 TiDB 使用环境】生产环境
【 TiDB 版本】8.1.0
【查询sql】
SELECT
summer.parent_hash_id as hash_id,summer.com_id
FROM
normal_summer summer
INNER JOIN basic_detail LISTING ON LISTING.com_id = 9
AND LISTING.delete_flag = 0
AND summer.store_id = LISTING.store_id
AND LISTING.asin = summer.asin
WHERE
summer.com_id = 123
AND summer.delete_flag = 0
AND summer.node_type IN (1, 2, 3)
GROUP BY
summer.parent_hash_id,com_id
当前业务所涉及的sql都类似上述sql,较多做了连表查询

【资源配置】16C64G nvme数据盘 13台tikv

【寻求解决】
如何设置相关参数,提高查询速度,当前平均速度为30S

1 个赞

执行计划发一下

辛苦风哥帮忙鉴定一下 :pray:

basic_detail表是不是没有tiflash副本?给它加tiflash副本,再看看执行计划。

思路就是,尽量用tiflash+mpp直接出结果。
具体到执行计划的样式上就是上面几行是root,下面全是mpp[tiflash],对你这个sql是最适合的。

你好呀 我这个detail表是做了tiflash同步的了

咱们有混布吗?

总共6台tidb 只有其中三台是和tidb和pd是混布的 配置为32C64G

SET @@session.tidb_allow_mpp = 1;
SET @@session.tidb_enforce_mpp = 1;
SET @@session.tidb_partition_prune_mode=dynamic;

session级把强制mpp打开,把动态分区裁剪也打开,再看看执行计划。
是否变成了像我上面描述的那样。

如果是,尝试实际执行一下,看看耗时。

如果不是,按下面这个方法看看为什么不能mpp

https://docs.pingcap.com/zh/tidb/stable/use-tiflash-mpp-mode#控制是否选择-mpp-模式

image
感谢您的回复 按照您的说法在修改级别修改 3s就可以出来结果 这个之前需要9-10s 我想全局设置应该如何操作 我添加了tidb_enforce_mpp: true 实际查询还是很慢

2 个赞


这样全走mpp了

1 个赞

非常符合预期,因为这个sql最好的处理方式就是tiflash+mpp,起码应该有2-10倍提升。

全局设置的问题是这样的,如果是global级别把这3个变量打开,可能对其他的sql有影响。

这就从一个sql优化的问题变成了一个架构的问题。即olap和oltp的隔离问题。

这个问题比较大,你有空可以看一下另一位大佬的文章,他系统的阐述了这个问题。

不把问题搞大,简单的来解决一下的话,

https://docs.pingcap.com/zh/tidb/stable/optimizer-hints#set_varvar_namevar_value

就是使用这个hint,单独的,只在这个sql运行的时候,这么设置一下这3个变量。

把前面的set @@session.去掉就是变量名=变量值。

2 个赞

explain analyze SELECT
SUMMARY.parent_hash_id as hash_id,SUMMARY.company_id
FROM
normal_summary SUMMARY
INNER JOIN basic_detail LISTING ON LISTING.company_id = 1
AND LISTING.delete_flag = 0
AND SUMMARY.id = LISTING.id
AND LISTING.a = SUMMARY.a
WHERE
SUMMARY.company_id = 1
AND SUMMARY.delete_flag = 0
AND SUMMARY.node_type IN (1, 2, 3)
GROUP BY
SUMMARY.parent_hash_id,company_id

猫哥 经过一晚上的叠加 昨天还可以3s 今天全走tiflash也要59s 这种情况还有救吗 因为数据量变多了

应该是并发多了吧。我感觉思路也就是3个,加资源,用缓存,用分页。

看看tiflash的同时期的监控图。

猫哥我的tiflash是单节点 64C256G 需要扩容吗 缓存是在哪里做呢

扩容问题,这要看监控,先看是不是这个问题。

缓存的问题,要从代码那边想办法了。

你这个捞取346W行,具体是个什么场景?我感觉不太像是给人看的,人一下看不了这么多。更像是导出然后进一步加工的。那就不需要一直实时的捞这么多。

早上好 猫哥 这个操作 346w是用户数据,他要做分页和多级排序

我感觉可以考虑直接用sql排序。别一次捞这么多。

猫哥 这是目前业务的难题 这是我们的想法

demo: select * from a inner join b on a.userId = b.userId where userId='xxxx' and 其他 order by id   ;  其中表a数据量1亿,表b数据量6亿,分区键用userId,分64个分区,耗时2秒;但是表a数据达到2亿时,该语句耗时变成30秒;
将分区键userId 改成id,是否有效果