首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择内部连接需要9小时(并计数)才能完成

选择内部连接需要9小时(并计数)才能完成
EN

Stack Overflow用户
提问于 2015-11-24 12:47:50
回答 2查看 98关注 0票数 0

我使用的是来自另一个脚本输出的sqlite数据库。我有一个查询需要花费大量的时间来完成。name**'s.samples表和multiclass表都有相同的~4,000,000行,多类表每个名称有一行(400万行),示例表可能对每个名称有一或多行(>一亿行)。

下面是我使用的模式和查询的一个玩具版本:

SQL Fiddle

SQLite (SQL.js)模式设置

代码语言:javascript
复制
CREATE TABLE samples 
    (
     name varchar(20), 
     day integer, 
     sample integer,
     count integer
    );

CREATE TABLE multiclass 
    (
     name varchar(20), 
     tax_id varchar(20), 
     details varchar(30)
    );

INSERT INTO samples
(name, day, sample, count)
VALUES
('seq1', 204, 37, 50),
('seq2', 205, 37, 50),
('seq2', 206, 37, 50),
('seq3', 204, 37, 50),
('seq4', 205, 37, 50),
('seq4', 206, 37, 50);

INSERT INTO multiclass
(name, tax_id, details)
VALUES
('seq1', 'Vibrio', 'unimportant'),
('seq2', 'Shewenella', 'still_unimportant'),
('seq3', 'Vibrio', 'also_unimportant'),
('seq4', 'Shewenella', 'doesntmatter');

查询1

代码语言:javascript
复制
SELECT tax_id, day, sample, SUM(count) 
FROM samples INNER JOIN multiclass USING(name) 
GROUP BY tax_id, day, sample 
ORDER BY day, sample;

结果

代码语言:javascript
复制
|     tax_id | day | sample | SUM(count) |
|------------|-----|--------|------------|
|     Vibrio | 204 |     37 |        100 |
| Shewenella | 205 |     37 |        100 |
| Shewenella | 206 |     37 |        100 |

我对SQL非常陌生,不知道如何继续。这是一个我认为只需要执行一次的查询。因此,我不确定向表中添加索引是否合适。

是否有不同的方法来构造查询以使其运行得更快?添加索引是有意义的还是太长了?如果花了9个小时,它可能仍然挂在SQL上吗,还是其他什么地方出错了?

编辑:更新了问题,包括数据库模式和预期结果。我目前正在samples.name列上构建索引,它已经运行了4个多小时(在集群环境中使用一个节点,其中有60G内存和多个cpus)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-08 16:52:11

问题是安装在我正在使用的集群上的sqlite3版本。集群上的版本为3.6.20。这似乎令人难以置信,但下载的二进制文件3.9.2从sqlite网站,并运行完全相同的查询在不到10分钟内完成。

票数 0
EN

Stack Overflow用户

发布于 2015-11-24 15:14:00

此查询:

代码语言:javascript
复制
SELECT tax_id, day, sample, SUM(count) 
FROM samples INNER JOIN
     multiclass
     ON samples.name = multiclass.name 
GROUP BY tax_id, day, sample 
ORDER BY day, sample;

很简单。通常建议在samples(name)multiclass(name)上建立索引。

但是,您的问题中有一个提示,即这两个表都包含400万行,但您只期望25,000行。我怀疑每个表中都有重复的名字。要确定join生成的中间行数,请运行以下查询:

代码语言:javascript
复制
select sum(s.cnt * m.cnt), max(s.cnt * m.cnt)
from (select name, count(*) as cnt from samples group by name
     ) s join
     (select name, count(*) as cnt from multiclass group by name
     ) m
     on s.name = m.name;

我猜您会得到一个非常大的数字,解释为什么查询要花这么长时间。

不幸的是,在这一点上,对于如何解决问题,我没有真正的答案,因为您的问题没有指定您实际上希望查询产生什么。但是,在加入这些表之前聚合它们可能是一种可能的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33894107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档