MySQL:选择数百万行

MySQL:选择数百万行,mysql,sql,Mysql,Sql,我有一个大约3200万行的数据集,我正试图导出它,为一个分析项目提供一些数据 由于我的最终数据查询将很大,所以我尝试限制最初必须处理的行数。我通过在主表(3200万条)记录上运行create table,在另一个约有5k条记录的表上运行join来实现这一点。我在连接发生的列上建立了索引,但没有在其他where条件上建立索引。此查询已运行了4个多小时 我能做些什么来加速这个过程?如果有什么事情,停止这个查询,这样做,然后重新开始是否值得?数据集是静态的,我不担心长期保存任何东西或正确的数据库设计。

我有一个大约3200万行的数据集,我正试图导出它,为一个分析项目提供一些数据

由于我的最终数据查询将很大,所以我尝试限制最初必须处理的行数。我通过在主表(3200万条)记录上运行create table,在另一个约有5k条记录的表上运行join来实现这一点。我在连接发生的列上建立了索引,但没有在其他where条件上建立索引。此查询已运行了4个多小时

我能做些什么来加速这个过程?如果有什么事情,停止这个查询,这样做,然后重新开始是否值得?数据集是静态的,我不担心长期保存任何东西或正确的数据库设计。我只需要把数据拿出来,然后放弃模式

下面是查询的简化版本

CREATE TABLE RELEVANT_ALERTS
SELECT a.time, s.name,s.class, ...
FROM alerts a, sig s
WHERE a.IP <> 0  
AND a.IP not between x and y
AND s.class in ('c1','c2','c3')
创建与表格相关的\u警报
选择a.time、s.name、s.class、。。。
来自警报a、信号s
其中a.IP 0
a.IP不在x和y之间
在('c1','c2','c3'中的s.class)

首先尝试“”查看是什么使其变慢,然后尝试添加一些索引(如果没有任何索引)

您的连接似乎是完全交叉连接。无论如何,这都需要很长时间。两个表中是否都没有公共字段?你为什么需要加入?如果确实要这样做,您应该首先从满足
WHERE条件的
警报和
sig
创建两个表,然后在必要时加入结果表。

首先尝试解释选择以查看发生了什么。索引设置是否正确?

您也没有用主键连接两个表,这是故意的吗?主键和外键在哪里

您还可以为我们提供一个表模式吗?

另外,您的硬件可能是问题所在吗?它有多少内存和处理能力?我希望您不是在单核处理器上运行这个,因为这肯定需要很长时间

我有一个2000000000(20亿行,219千兆)的表,在正确设置索引的情况下执行类似的查询不需要超过0.3秒。这是在一个具有64gb ram的8(2ghz)核心处理器上实现的。因此,不是数据库大小的最佳设置,而是索引保存在内存中,因此查询可以很快进行

应该不会花那么长时间。你能确定你在a.IP和s.class上有索引吗

你也不能把a.IP=0的比较放在a.IP之后,而不是放在x和y之间,所以你已经有了一个0比较的过滤集(因为这将比较我相信的每一条记录)


您可以将s.class作为第一个比较来移动,这取决于s表必须实际加速比较的行数

相信我,4小时是很正常的:因为你有一个3200万行的表,使用join只需将3200万行乘以5000,所以你的查询的复杂度是32000000*5000…
为了避免这种情况,我建议您使用ETL工作流。。。像微软SSIS。。。 使用SSIS,您可以大大减少查询时间…

同意Vish

此外,根据您的查询工作负载,您可能会将内部存储引擎更改为MyISAM,如果它当前是InnoDB,因为Mysiam更适合于只读查询

ALTER TABLE my_table ENGINE = MyISAM;
此外,您还可以更改数据库的名称。例如,要将隔离级别设置为“读取未提交”:

SET tx_isolation = 'READ-UNCOMMITTED';

为什么不限制查询返回的记录数呢<代码>限制5000
我必须检查所有记录以找到我需要的。我使用此查询将主表精简为一个更易于管理的表,以便对其运行其他“报告”查询。考虑到所涉及的时间,我不想让查询运行数百次。因此,请确保您的表中有pk和fk,并且不要像您这样进行交叉连接。您的问题解决了吗?如果将答案标记为正确的话,是否应该盲目地添加索引?他们应该如何添加索引?什么栏目?你能包括“解释选择”的语法吗?实际上我在开始之前已经运行了一个解释。这让我创建了一个索引,但随后的解释没有显示任何区别。@GeorgeStocker这里是关于的文档,基本上这是一种查看查询引擎如何处理语句而不必运行语句的方法。@user3195248我知道解释是什么,它是做什么的;我发表评论的动机是以温和的方式让OP知道为什么他的答案会被否决/被标记。@GeorgeStocker——非常抱歉,我在回复中标记了错误的用户。4小时是不正常的,也不应该是正常的。这是可以解决的。。。比如用正确的索引创建子表,这样您就可以连接它们(而不是交叉连接)。。。设置正确时可能需要几秒钟。我只是尝试在两个表之间创建一个FK,但由于警报表已分区,因此我无法创建FK。我不是故意这样做的,但可能是从原始源数据库中这样做的。你能给我架构的详细信息吗,即使它是分区的。这篇文章指出了正确的方向,我更改了where子句的顺序,并创建了一些新的索引。这将查询时间缩短到大约一分钟。考虑到我使用的硬件,这是合理的。我很高兴它现在能工作。如果您有任何其他问题,请与我联系。