【发布时间】:2018-12-12 04:37:56
【问题描述】:
我在 MySQL8 中遇到了窗口函数的问题 - 它们在应用于大型表时会给出不正确的结果(或者:大量行或大量列)。
示例: 表:office.csv(170 万行)来自https://www.kaggle.com/c/home-credit-default-risk/data
我运行 3 个简单查询,仅更改要使用的表的行数和要输出的列数。您可以清楚地看到,大量行和许多输出列的组合给出了“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) SHOW GLOBAL STATUS; C) 显示全局变量; D) 显示 ENGINE INNODB 状态; SHOW CREATE TABLE 局; part1 part2
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
;
【问题讨论】:
-
为什么会出错? MySQL docs cleary 声明窗口函数适用于行“窗口函数对一组查询行执行类似聚合的操作。但是,虽然聚合操作将查询行分组为单个结果行,但窗口函数会为每个查询行生成一个结果查询行:"源dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html
-
请在此处以纯文本形式发布代码、错误、示例数据或文本输出,而不是难以阅读的图像,不能复制粘贴以帮助测试代码或在答案中使用,并且对使用屏幕阅读器的人怀有敌意。您可以编辑问题以在问题正文中添加代码。使用
{}按钮格式化任何代码块,或使用四个空格缩进以获得相同的效果。 很遗憾,我们无法将您的屏幕截图作为代码运行。 -
@RaymondNijland 每行的“count(*) over(partition by b.sk_id_curr)”的正确结果是共享相同 b._sk_id_curr 值的行数。
-
@tadman 已经提供了数据表的链接,代码是经典的“单线”,但我会为您提供。
-
内联代码比链接好很多。谢谢。
标签: mysql large-data window-functions mysql-8.0