Python 大表上的非常慢的联接查询(机器=Xeon 2.4 GHz,16核,64 GB RAM)
我的问题是:Python 大表上的非常慢的联接查询(机器=Xeon 2.4 GHz,16核,64 GB RAM),python,mysql,sql,performance,Python,Mysql,Sql,Performance,我的问题是: SELECT email_data.id, email_data.source_file, email_data.report_id, email_data.filePath, email_data.fileName, email_data.size, email_data.emailID, email_data.msgID, email_data.cus, email_data.subject, email_data.sentto
SELECT email_data.id, email_data.source_file, email_data.report_id,
email_data.filePath, email_data.fileName, email_data.size,
email_data.emailID, email_data.msgID, email_data.cus, email_data.subject,
email_data.sentto, email_data.emailFrom, email_data.hdrs, email_data.cc,
email_data.bcc, email_data.extracted, email_data.DateTime,
email_data.TimeStamp, email_data.OriginalDateTime, email_data.ParentID,
email_data.reply_to, email_data.MD5Hash, email_data.duplicated,
email_data.TimeZone, email_data.AttachName, email_data.fqdn,
attach_data.id, attach_data.source_file, attach_data.report_id,
attach_data.filePath, attach_data.fileName, attach_data.size, attach_data.ext,
attach_data.emailID, attach_data.cus, attach_data.extracted,
attach_data.MD5Hash, attach_data.duplicated
FROM email_data
LEFT JOIN attach_data
ON (email_data.emailID = attach_data.emailID);
这两个表的组合有50k+条记录(电子邮件数据有22k条记录,其他有30K+条记录)
上述查询需要90多分钟,但仍未完成
这个:
SELECT email_data.id, attach_data.id
FROM email_data
LEFT JOIN attach_data
ON (email_data.emailID = attach_data.emailID);
需要2分钟22秒:
我做错了什么?MySQL似乎没有使用足够的内存来加快速度,它只使用了16个内核中的1个
如何将其配置为使用所有可用资源
或者我应该查询ID(如第二次查询)并在代码中循环+选择每个ID?这会导致同样的结果吗
我需要所有这些字段和所有行,我正在将它们转换为自定义CSV格式,以便可以导出到其他软件
栏目:
mysql> show columns from email_data;
+------------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| source_file | longtext | YES | | NULL | |
| report_id | int(11) | YES | | NULL | |
| filePath | longtext | YES | | NULL | |
| fileName | longtext | YES | | NULL | |
| size | int(11) | YES | | NULL | |
| emailID | longtext | YES | | NULL | |
| msgID | longtext | YES | | NULL | |
| cus | longtext | YES | | NULL | |
| subject | longtext | YES | | NULL | |
| sentto | longtext | YES | | NULL | |
| emailFrom | longtext | YES | | NULL | |
| hdrs | longtext | YES | | NULL | |
| cc | longtext | YES | | NULL | |
| bcc | longtext | YES | | NULL | |
| extracted | longtext | YES | | NULL | |
| DateTime | char(1) | YES | | NULL | |
| TimeStamp | int(11) | YES | | NULL | |
| OriginalDateTime | char(1) | YES | | NULL | |
| ParentID | longtext | YES | | NULL | |
| reply_to | longtext | YES | | NULL | |
| MD5Hash | longtext | YES | | NULL | |
| duplicated | char(1) | YES | | NULL | |
| TimeZone | char(1) | YES | | NULL | |
| AttachName | longtext | YES | | NULL | |
| fqdn | longtext | YES | | NULL | |
+------------------+----------+------+-----+---------+----------------+
“附加数据”几乎是一样的,你真的想把表中的所有行都去掉吗?如果您可以在流程中的特定时刻使用较小的查询来查询所需的内容,那会更好。理想情况下,您可以在某处添加where子句。真正的滞后可能是从硬盘读取。使用递归备份进行RAID设置可能会加快速度,但我不确定 您可以更改一些MySQL设置,告诉它每个查询使用的最大内存量以及其他一些选项
您真的想要表中的所有行吗?如果您可以在流程中的特定时刻使用较小的查询来查询所需的内容,那会更好。理想情况下,您可以在某处添加where子句。真正的滞后可能是从硬盘读取。使用递归备份进行RAID设置可能会加快速度,但我不确定 您可以更改一些MySQL设置,告诉它每个查询使用的最大内存量以及其他一些选项
不确定如何使查询运行90分钟而不是超时 检查您要加入的字段。具体来说,请查看查询的执行计划(或估计的执行计划),以了解成本最高的操作是什么 您正在加入varchar(255)字段。varchar(最大值)或类似值?比较大型VARCHAR是一项昂贵的操作。如果你能缩短场地,那会有帮助的 关于所有这些领域: 返回较小的字段子集。如果要从sql server调用实际的附件数据,则可能需要首先执行查询,以确定需要哪些附件(attach_data.PrimaryKey),而不是整行(随后必须将其拉入内存)。 然后,一旦获得了所需的attach_数据记录的PKs,就只能调用这些行所需的数据
您是否加入了非索引字段(如您没有加入主键)?向列中添加索引将加快检索过程,但在这样做之前先了解索引(例如,向列中添加索引实际上会减慢数据更新/插入速度,int字段上的索引比大范围varchar上的索引要好)。不确定如何使查询运行90分钟而不是超时 检查您要加入的字段。具体来说,请查看查询的执行计划(或估计的执行计划),以了解成本最高的操作是什么 您正在加入varchar(255)字段。varchar(最大值)或类似值?比较大型VARCHAR是一项昂贵的操作。如果你能缩短场地,那会有帮助的 关于所有这些领域: 返回较小的字段子集。如果要从sql server调用实际的附件数据,则可能需要首先执行查询,以确定需要哪些附件(attach_data.PrimaryKey),而不是整行(随后必须将其拉入内存)。 然后,一旦获得了所需的attach_数据记录的PKs,就只能调用这些行所需的数据
您是否加入了非索引字段(如您没有加入主键)?向列中添加索引将加快检索过程,但在这样做之前先了解索引(例如,向列中添加索引实际上会减慢数据更新/插入,int字段上的索引比大范围varchar上的索引要好)。几乎可以肯定
附加数据。emailID
缺少索引。假设查询引擎必须遍历电子邮件数据的每一行,如果缺少索引,则即使在找到匹配之后,它也必须遍历附件行的每一行。
您应该对查询运行解释,以查看MySql实际上在做什么。如果缺少索引,您将进行22000 x 30000次比较,或者大约6.6亿次比较,以建立结果数据集。如果你的id是字符串,那么你将有一段很长的旅程
如果您使用indexattach_data.emailId
,您将把比较次数减少到22000 x log(30000)左右,即大约330 000次比较。差别很大。使用散列
索引将使这一过程更快(下限为22000次比较)。如果缺少索引,可以在事后附加它们
<>和诚实地,你应该考虑 Lime 跳过并取一个结果窗口。这将为您在与客户机的数据交换中节省大量的时间。你可能会发现这种流量会导致慢速连接超时(我同意另一张海报,奇怪的是你没有超时)
更新
天哪。看到你对这个问题的更新,你肯定应该只收回非长文本字段,迭代这些字段,然后一次收回一个长文本字段。但考虑到您需要将mysql表转储到csv,我建议您研究一下。它可以为您将数据库备份到CSV文件。几乎可以肯定的是attach\u data.em