1

我在 MySQL8 中遇到了窗口函数的问题 - 它们在应用于大型表时会给出不正确的结果(或者:大量行或大量列)。

示例:表:来自https://www.kaggle.com/c/home-credit-default-risk/data的 Bureau.csv(170 万行)

我运行 3 个简单查询,仅更改要使用的表的行数和要输出的列数。您可以清楚地看到,大量行和许多输出列的组合给出了“count(*) over()”的错误结果 - 最后一列。

行数多,列数少 - 结果:OK;

行数多,列数多 - 结果:不正确;

行数少,列数高 - 结果:OK;

Ubuntu 16.04,32GB 内存

非常感谢您的帮助!:)

维托德

my.cnf:
[mysqld]

innodb_buffer_pool_size = 26G
default_authentication_plugin=mysql_native_password
thread_cache_size = 50
innodb-flush-method=O_DIRECT
local_infile=ON
innodb_thread_concurrency=2
internal_tmp_mem_storage_engine=MEMORY
join_buffer_size=1G
temptable_max_ram=4G
tmp_table_size=4G
max_heap_table_size=4G
mysqlx_connect_timeout=99999
mysqlx_read_timeout=99999
mysqlx_write_timeout=99999
net_read_timeout=99999
net_write_timeout=99999
regexp_time_limit=99999
mysqlx_port_open_timeout=99999
windowing-use-high-precision=OFF
sort_buffer_size=4G

要运行的代码:

select a.*
from
(
select #b.sk_id_curr,
       b.*,
       count(*) over(partition by b.sk_id_curr) as counter
from (select * from bureau limit 10000000) b
) a
order by a.sk_id_curr desc
limit 100
;

编辑: 解释和索引图片

还有一件事我注意到:在“不正确”图片中,所有列都不正确(不仅是最后一个) - 与“GOOD”结果的图片进行比较”(查看 sk_id_curr)。

根据 Wilson Hauck 的要求:A)完整(未编辑)my.cnf-ini 文本结果:B)显示全球状态;C) 显示全局变量;D) 显示 ENGINE INNODB 状态;SHOW CREATE TABLE 局; 第 1部分 第 2 部分

DB Fiddle 上的 1000 行示例:https ://www.db-fiddle.com/f/fzXsN6vFzidhanxeUjWkiB/0

我将数据导入mysql的方式:

首先,我将 csv 中的“空格”替换为 python 中的“NULL”:

import pandas as pd
bureau = pd.read_csv('../input/bureau.csv')
bureau.to_csv('../input/bureau2.csv',index=False,na_rep="NULL",header=True)

其次我在mysql中使用了代码:

LOAD DATA LOCAL INFILE '../input/bureau2.csv' INTO TABLE bureau
FIELDS TERMINATED BY ',' ENCLOSED BY '"' 
LINES TERMINATED BY '\n'
IGNORE 1 LINES
;
4

3 回答 3

0

为您的 my.cnf-ini [mysqld] 部分考虑的建议

temptable_max_ram=320M # from 4G for 1 percent of RAM 
tmp_table_size=320M # from 4G for 1 percent of RAM 
max_heap_table_size=320M # from 4G for 1 percent of RAM 
innodb_thread_concurrency=0 # from 2 throttle choking your server 
innodb_buffer_pool_size=24G # from 26G for 80% of RAM 
innodb_change_buffer_max_size=10 # from 25 percent set aside 
# sort_buffer_size=4G for default 
# join_buffer_size=4G for default 

只有 32G RAM,您要求 26G、1G、4G、4G、4G、4G = 43G 没有给 MySQL 和 OS 留下任何东西?

如需更多帮助,请查看配置文件、网络配置文件以获取联系信息。

于 2018-07-18T14:00:01.070 回答
0

我下载了 Bureau.csv 并使用您的表格将其导入,如您的“第 2 部分”链接所示。我不得不禁用严格模式

set session sql_mode='';)

否则我在加载数据时出错

(load data  infile 'bureau.csv' into table bureau columns terminated by "," ignore 1 lines;

不过,我的统计数据与您的略有不同: 显示局的索引

然后我运行了你失败的查询并得到了预期的结果:

在此处输入图像描述

您使用的是哪个版本的 MySQL 8?

查询的文本版本:

select a.*
   from
   (
   select #b.sk_id_curr,
          b.*,
          count(*) over(partition by b.sk_id_curr)
   from (select * from bureau limit 10000000000) b
   ) a
   order by a.sk_id_curr desc
   limit 100
   ;
于 2018-07-23T17:24:55.353 回答
0

这个版本为我提供了 8.0.11 的预期结果(注意不再有任何文本 blob)。如果您设置了 --big_tables 以使其正常工作,您还需要禁用它。

CREATE TABLE `bureau` (
 `SK_ID_CURR` int(11) DEFAULT NULL,
 `SK_ID_BUREAU` int(11) DEFAULT NULL,
 `CREDIT_ACTIVE` varchar(20),
 `CREDIT_CURRENCY` varchar(20),
 `DAYS_CREDIT` int(11) DEFAULT NULL,
 `CREDIT_DAY_OVERDUE` int(11) DEFAULT NULL,
 `DAYS_CREDIT_ENDDATE` varchar(20),
 `DAYS_ENDDATE_FACT` varchar(20),
 `AMT_CREDIT_MAX_OVERDUE` varchar(20),
 `CNT_CREDIT_PROLONG` int(11) DEFAULT NULL,
 `AMT_CREDIT_SUM` double DEFAULT NULL,
 `AMT_CREDIT_SUM_DEBT` varchar(20),
 `AMT_CREDIT_SUM_LIMIT` varchar(20),
 `AMT_CREDIT_SUM_OVERDUE` double DEFAULT NULL,
 `CREDIT_TYPE` varchar(20),
 `DAYS_CREDIT_UPDATE` int(11) DEFAULT NULL,
 `AMT_ANNUITY` varchar(20),
 KEY `bureau` (`SK_ID_CURR`,`SK_ID_BUREAU`),
 KEY `bureau_i2` (`SK_ID_BUREAU`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

set session sql_mode='';
load data infile '/export/home/tmp/dag/git/mysql/bureau.csv' into table bureau columns terminated by "," ignore 1 lines;


select a.*
from
(
select #b.sk_id_curr,
       b.*,
       count(*) over(partition by b.sk_id_curr) as counter
from (select * from bureau) b
) a
order by a.sk_id_curr desc
limit 100
;
于 2018-07-27T01:43:43.317 回答