count全表扫描非常慢

【 TiDB 使用环境】
7台配置是16核32G

【概述】 场景 + 问题概述
6千多万的数据,页面是分页列表,然而,使用select count(1) from xx where xx in ()的时候就已经走全表扫描了,很慢
1651108091(1)
【背景】 做过哪些操作
给需要过滤字段添加索引,并没有用
【现象】 业务和数据库现象
查询非常慢


查看索引,使用全表扫描

【问题】 当前遇到的问题

【业务影响】

【TiDB 版本】
5.3
【应用软件及版本】

【附件】 相关日志及配置信息

  • TiUP Cluster Display 信息
  • TiUP CLuster Edit config 信息

监控(https://metricstool.pingcap.com/)

  • TiDB-Overview Grafana监控
  • TiDB Grafana 监控
  • TiKV Grafana 监控
  • PD Grafana 监控
  • 对应模块日志(包含问题前后 1 小时日志)

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

2 个赞

你好。请提供下:

  1. 表结构;
  2. 表健康度;(SHOW STATS_HEALTHY WHERE db_name = ? AND table_name = ?
  3. select count(1) from xxselect count(1) from xx where xx in () 的执行计划。(你只给出了一个执行计划)

通过分析你的问题描述,我感觉是优化器觉得全表扫和走索引(如果有有效索引)代价基本相差不大,所以直接走全表扫了。
%E5%9B%BE%E7%89%87
%E5%9B%BE%E7%89%87

加不加 where 条件,结果差距很小。你可以尝试 where in 放两个值试试,对比下效果。

2 个赞

count(*)慢不慢?

2 个赞

一样慢

2 个赞

看看执行计划,表健康度,是不是要做一下统计分析

2 个赞
  1. 表结构

    2.健康度
    1651112735(1)
    3.count(1)的执行计划

    官网上说当in中数据量较小时会走索引,试过了当in中20个以内会走索引
2 个赞

加in的过滤条件59808311/60249041=0.9927, 任何一个正常工作的数据库都会选择全表扫描,贴下explain analyze的执行结果

2 个赞

从目前提供的信息看,这个结果是预期的。count 的结果走索引跟全表扫基本没区别,而且 del_flag 还没有索引可以走。
%E5%9B%BE%E7%89%87

3 个赞


是有条件关联查询的情况,为了避免使用join关联,就采用了先查第一张表,再在这种表种使用in,至少是单表查询,如果是关联就更慢

1 个赞

explain analyze看下后部分execution info。 加了in过滤条件99%的数据量返回和全表扫没太大区别,走个索引在回表查询更慢

2 个赞

del_flag是删除标志,只有0和1两个值,有没有索引影响应该不大

1 个赞


但是因为这个,导致了回表操作。
主要还是你 where in 的过滤效果太低了(5900W 那个例子),近似没有 where 条件。

1 个赞

全表一定不快的。用tiflash了吗?

1 个赞

是有条件关联查询的情况,为了避免使用join关联,就采用了先查第一张表,再在这种表种使用in,至少是单表查询,如果使用join,一张60万左右表和一张6千万表进行关联,那没法查

1 个赞

我明白你的真实场景,应该是 select count(1) from a where xxx and xxx in (select subquery) 这种吧。
你这个属于聚合分析场景,如果走全表扫肯定很慢,最好是能完全走索引统计出结果,你可以尝试优化下 SQL,看能不能实现完全走索引。(直接 explain analyze 看真实执行计划,慢慢调优下,当然应该在非生产环境)

1 个赞


后面信息有点长,按照这个顺序,我复制出来

其实你可以直接上传执行计划这个文件。:grinning:

用了,两台tiflash

tidb cpu (tidb监控),tidb和tikv的网络延迟(blackexporter监控)看下

手动更新统计信息收集,查看执行计划 ,优化一下sql语句 分析一下 看看能不能走索引 尝试一下

1 个赞