zoukankan      html  css  js  c++  java
  • 语句执行错误一· Count(Distinct) ERROR

    背景

      MySQL现行版本中存在一个count(distinct)语句返回结果错误的bug,表现为,实际结果存在值,但是用count(distinct)统计后返回的是0。

    drop table if exists tb;
    set tmp_table_size=1024;
    create table tb(id int auto_increment primary key, v varchar(32)) charset=gbk;
    insert into tb(v) values("aaa");
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    insert into tb(v) (select v from tb);
    update tb set v=concat(v, id);
    select count(distinct v) from tb;
    返回0
    
    上述中update语句的目的是将所有的v值设为各不相同。

    原因分析

      Count(distinct f)的语义就是计算字段f的去重总数,计算流程大致如下:

      流程一:

    1. 构造一个unique集合A1(用tree实现) 2、 对每个值都试图插入集合A1中 3、 若和A1中现有item重复则直接跳过,不重复则插入并+1 4、 完成后计算集合中元素个数。

      细心的同学会看到上面的语句中有一个set tmp_table_size的过程,集合A1并不能无限扩大,大小上限为tmp_table_size。若超过则上述流程变为

      流程二:

    1. 构造一个unique 集合A1 2、 插入item过程中若大小超过tmp_table_size,则将A1暂时写到文件中,再构造集合A2 3、 重复步骤2直到所有的item插入完成 因此若item很多则可能重复生成多个集合A1~An。 4、 对A1~An作合并操作。由于只是每个集合A保证unique,因此需要做类似归并排序的操作(实际上不需要排序,只是扫一遍) 5、 因此合并操作需要一个临时内存,长度为n,单元大小为key_length (key大小)。这个临时内存,用的也是tmp_table_size定义的大小。实际上在合并过程中还需要长为key_length的预留空间作临时内存保存。因此需要的空间为 (n+1)key_length。 6、 在进行合并前会判断tmp_table_size >=(n+1)key_length, 不满足则直接放弃合并。其结果就是返回为0

    解决方法

      运维上,set sql_big_tables是一个方法,不过会影响性能。调高tmp_table_size算是正招。当然本质上这是一个bug。   代码上,对于已经走到合并操作的这个逻辑,如果tmp_table_size不够,应该直接申请新的临时空间用于合并,完成后释放。虽然会造成临时征用内存,不过以现有的逻辑来看,临时征用的内存已经不少了.

    螃蟹在剥我的壳,笔记本在写我,漫天的我落在枫叶上雪花上,而你在想我。 --章怀柔
  • 相关阅读:
    [译文] 实体与值对象到底是不是一回事?
    实现 WebApi 自托管服务宿主于 WinForms 及其交互
    [译文] C# 8 已成旧闻, 向前, 抵达 C# 9!
    [译文] 为什么你在 C# 里总是应该使用 "var" 关键字
    通过设置iis在局域网中访问网页
    windows 10 安装使用kafka
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 2) 定义命名化和类型化的客户端
    Asp.net Core 2.0 OpenId Connect Handler缺失Claims?
  • 原文地址:https://www.cnblogs.com/lovezhr/p/13263045.html
Copyright © 2011-2022 走看看