You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL8中PRIMARY.n_diff_pfx01与主键唯一计数不匹配问题咨询

主键索引统计值与表行数不匹配的问题排查与解决

表结构信息

create table employees
(
    emp_no int not null primary key,
    birth_date datetime not null,
    first_name varchar(14) not null,
    last_name varchar(16) not null,
    gender enum('M', 'F') not null,
    hire_date datetime not null,
    full_name varchar(50) as (concat(`first_name`,_utf8mb4' ',`last_name`))
)
collate=utf8mb4_general_ci;

create index ix_firstname
    on employees (first_name);

create index ix_fullname
    on employees (full_name);

create index ix_gender_birthdate
    on employees (gender, birth_date);

create index ix_hiredate
    on employees (hire_date);

create index ix_lastname_firstname
    on employees (last_name, first_name);

create definer = root@localhost trigger on_delete
    before delete
    on employees
    for each row
    BEGIN
         DELETE FROM salaries WHERE emp_no=OLD.emp_no; 
       END;

该表共包含300,204行数据,已设置STATS_PERSISTENT=1启用持久化统计。

异常现象

主键emp_no为唯一值,按逻辑PRIMARY索引的n_diff_pfx01(即emp_no的唯一值数量)应与表行数完全一致,但实际统计结果显示PRIMARY.n_diff_pfx01=299,101,与表行数300,024不匹配。

统计结果详情

//Primary.n_diff_pfx01 is 299,101 but table row count is 300,024
database_nametable_nameindex_namelast_updatestat_namestat_valuesample_sizestat_description
employeesemployeesPRIMARY2022-10-12 22:44:12n_diff_pfx0129910120emp_no
employeesemployeesPRIMARY2022-10-12 22:44:12n_leaf_pages965NULL索引中的叶子页数
employeesemployeesix_firstname2022-10-12 22:44:12n_diff_pfx01127920first_name
employeesemployeesix_firstname2022-10-12 22:44:12n_diff_pfx0229928620first_name,emp_no
employeesemployeesix_firstname2022-10-12 22:44:12n_leaf_pages496NULL索引中的叶子页数
employeesemployeesix_firstname2022-10-12 22:44:12size609NULL索引中的总页数
employeesemployeesix_fullname2022-10-12 22:44:12n_diff_pfx0128072920full_name
employeesemployeesix_fullname2022-10-12 22:44:12n_diff_pfx0229638320full_name,emp_no
employeesemployeesix_fullname2022-10-12 22:44:12n_leaf_pages478NULL索引中的叶子页数
employeesemployeesix_fullname2022-10-12 22:44:12size609NULL索引中的总页数

原因分析

  1. 采样统计偏差:InnoDB持久化统计默认采用采样方式计算唯一值数量,从统计结果可见sample_size=20,仅采样了20个索引页。对于主键这种全唯一值的索引,少量采样页无法覆盖所有数据,导致统计值与实际行数存在偏差。
  2. 统计信息未及时更新:若表发生大量数据插入、删除操作后,统计信息未自动触发更新,也会导致统计值滞后于实际数据。

解决办法

  1. 增大采样页面数:调整采样页数量,让统计采样更全面。可全局设置或针对单表设置:
    -- 全局设置
    SET GLOBAL innodb_stats_persistent_sample_pages = 100;
    -- 单表设置
    ALTER TABLE employees STATS_SAMPLE_PAGES = 100;
    
  2. 手动刷新统计信息:执行命令强制更新表的统计数据,确保统计值与实际数据一致:
    ANALYZE TABLE employees;
    
  3. 验证结果:重新查询统计信息,确认PRIMARY.n_diff_pfx01是否与表行数匹配。

内容的提问来源于stack exchange,提问作者haedoang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:31:06