mysql 8 window 函数错误结果
mysql 8 window function wrong results
我对 MySQL8 中的 window 函数有疑问 - 当应用于大 tables(或者:大量行或大量列)时,它们给出不正确的结果.
示例:
Table:bureau.csv(170 万行)来自 https://www.kaggle.com/c/home-credit-default-risk/data
I 运行 3 个简单查询仅更改要使用的 table 的行数和要输出的列数。您可以清楚地看到大量行和许多输出列的组合给出了 "count(*) over()" - 最后一列的错误结果。
high number of rows, low number of columns - result: OK;
high number of rows, high number of columns - result: INCORRECT;
low number of rows, hight number of columns - result: 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
;
编辑:
exlain and indexes picture
还有一件事我注意到:在 "INCORRECT" 图片中所有列都不正确(不仅是最后一列)- 与具有 "GOOD" 结果的图片进行比较”(查看 sk_id_curr).
根据 Wilson Hauck 的要求:A) 完整(未编辑)my.cnf-ini 文本结果:B) 显示全球状态; C) 显示全局变量; D) 显示引擎创新状态;显示创建 TABLE 局;
part1
part2
DB Fiddle 上的样本 1000 行:https://www.db-fiddle.com/f/fzXsN6vFzidhanxeUjWkiB/0
我将数据导入mysql的方式:
首先 我用 python:
中的 "NULL" 替换了 csv 中的 "blank spaces"
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
;
关于 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?
如需更多帮助,请查看个人资料、网络个人资料以获取联系信息。
我下载了 bureau.csv 并使用您的 table 导入了它,如您的 'part2' link 所示。我不得不禁用严格模式
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
;
此版本为我提供了 8.0.11 的预期结果(注意不再有任何文本斑点)。您还需要禁用 --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
;
我对 MySQL8 中的 window 函数有疑问 - 当应用于大 tables(或者:大量行或大量列)时,它们给出不正确的结果.
示例: Table:bureau.csv(170 万行)来自 https://www.kaggle.com/c/home-credit-default-risk/data
I 运行 3 个简单查询仅更改要使用的 table 的行数和要输出的列数。您可以清楚地看到大量行和许多输出列的组合给出了 "count(*) over()" - 最后一列的错误结果。
high number of rows, low number of columns - result: OK;
high number of rows, high number of columns - result: INCORRECT;
low number of rows, hight number of columns - result: 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
;
编辑: exlain and indexes picture
还有一件事我注意到:在 "INCORRECT" 图片中所有列都不正确(不仅是最后一列)- 与具有 "GOOD" 结果的图片进行比较”(查看 sk_id_curr).
根据 Wilson Hauck 的要求:A) 完整(未编辑)my.cnf-ini 文本结果:B) 显示全球状态; C) 显示全局变量; D) 显示引擎创新状态;显示创建 TABLE 局; part1 part2
DB Fiddle 上的样本 1000 行:https://www.db-fiddle.com/f/fzXsN6vFzidhanxeUjWkiB/0
我将数据导入mysql的方式:
首先 我用 python:
中的 "NULL" 替换了 csv 中的 "blank spaces"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
;
关于 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?
如需更多帮助,请查看个人资料、网络个人资料以获取联系信息。
我下载了 bureau.csv 并使用您的 table 导入了它,如您的 'part2' link 所示。我不得不禁用严格模式
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
;
此版本为我提供了 8.0.11 的预期结果(注意不再有任何文本斑点)。您还需要禁用 --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
;