在大型数据集上使用 JOIN 运行 SQL 查询
Posted
技术标签:
【中文标题】在大型数据集上使用 JOIN 运行 SQL 查询【英文标题】:Running SQL queries with JOINs on large datasets 【发布时间】:2015-01-22 14:57:53 【问题描述】:我刚开始使用 mysql。
我正在尝试在包含 80,000 条记录(这是表 B)的数据库与大约 6 亿条记录(这是表 A)的 40GB 数据集之间运行内连接查询
Mysql 适合运行这种查询吗? 我预计需要多长时间?
这是我在下面的代码。但是它失败了,因为我的 dbs 连接在 60000 秒时失败。
set net_read_timeout = 36000;
INSERT
INTO C
SELECT A.id, A.link_id, link_ref, network,
date_1, time_per,
veh_cls, data_source, N, av_jt
from A
inner join B
on A.link_id = B.link_id;
我开始研究将 40GB 表大小缩减为临时表的方法,以尝试使查询更易于管理。但我不断得到
错误代码:1206。锁的总数超过了锁表大小 646.953 秒
我在正确的轨道上吗? 干杯!
我拆分数据库的代码是:
LOCK TABLES TFM_830_car WRITE, tfm READ;
INSERT
INTO D
SELECT A.id, A.link_id, A.time_per, A.av_jt
from A
where A.time_per = 34 and A.veh_cls = 1;
UNLOCK TABLES;
也许我的表索引是正确的,我只有一个简单的主键
CREATE Table A
(
id int unsigned Not Null auto_increment,
link_id varchar(255) not Null,
link_ref int not Null,
network int not Null,
date_1 varchar(255) not Null,
#date_2 time default Null,
time_per int not null,
veh_cls int not null,
data_source int not null,
N int not null,
av_jt int not null,
sum_squ_jt int not null,
Primary Key (id)
);
Drop table if exists B;
CREATE Table B
(
id int unsigned Not Null auto_increment,
TOID varchar(255) not Null,
link_id varchar(255) not Null,
ABnode varchar(255) not Null,
#date_2 time not Null,
Primary Key (id)
);
就架构而言,只是在数据库下加载的这两个表(A 和 B)
【问题讨论】:
“针对 40GB 数据集”。有多少记录?您的表格是否正确编入索引? 80k 记录对于这么多的数据来说似乎相当少,你在那里存储什么,XML 转储,图像二进制文件? 您可以通过从子查询(派生表)中进行选择来绕过该错误,但这并不能解决性能问题。发布您的架构和一些示例数据以获得进一步的帮助。 嗨 tomasz,很抱歉将其清除 hamitn_north 表中有 80k 条记录和 【参考方案1】:感谢您的帮助。
索引似乎已经解决了这个问题。我设法通过索引将查询时间从 700 秒减少到每条记录大约 0.2 秒:
A.link_id
即来自
from A
inner join B
on A.link_id = B.link_id;
发现这篇非常有用的帖子。 v 对像我这样的新手很有帮助
http://hackmysql.com/case4
用于索引的代码是:
CREATE INDEX linkid_index ON A(link_id);
【讨论】:
【参考方案2】:我相信这个帖子已经给出了答案:The total number of locks exceeds the lock table size
即。使用表锁来避免 InnoDB 默认的逐行锁模式
【讨论】:
以上是关于在大型数据集上使用 JOIN 运行 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章
基于条件的 2 个大型数据集上的模糊模糊字符串匹配 - python
Dataflow Bigquery-Bigquery 管道在较小的数据上执行,但不是在大型生产数据集上执行