我有一个mysql查询,计算通过特定过滤器(时间过滤器和免费搜索)的电子邮件数量
查询目前在我的服务器上至少需要30秒(时间间隔只有12天),所以我想让它更有效率。
我没有很多mysql的经验,所以请对我温柔一点。
当前查询是:
SELECT
count(distinct emls.EML_ID) as count FROM origins
JOIN emls ON emls.EML_ID = origins.source_id
JOIN email2addresses ON emls.EML_ID = email2addresses.EML_ID
JOIN email_addresses ON email_addresses.Email_ID = email2addresses.Email_ID
JOIN files ON files.Origin_ID = origins.Origin_ID
JOIN unique_files ON unique_files.Unique_File_ID = files.Unique_File_ID
WHERE origins.insert_date BETWEEN FROM_UNIXTIME(1533323333) and FROM_UNIXTIME(1534323333)
and (origins.source_id LIKE "%%" or emls.Subject LIKE "%%"
or email_addresses.Email_Address LIKE "%%" or files.File_Name LIKE "%%"
or files.File_ID LIKE "%%" or unique_files.File_Hash LIKE "%%");
运行时 explain
在我得到查询之前:
1 SIMPLE origins index PRIMARY,Source_ID_index Source_ID_index 5 10699008 11.11 Using where; Using index
1 SIMPLE emls eq_ref PRIMARY PRIMARY 4 origins.Source_ID 1 100.00
1 SIMPLE files ref Unique_File_ID_index,Origin_ID_index Origin_ID_index 5 origins.Origin_ID 1 100.00 Using where
1 SIMPLE unique_files ref PRIMARY PRIMARY 4 files.Unique_File_ID 1 100.00
1 SIMPLE email2addresses ref EML_ID_index,Email_ID_index EML_ID_index 5 origins.Source_ID 4 100.00 Using where
1 SIMPLE email_addresses eq_ref PRIMARY PRIMARY 4 email2addresses.Email_ID 1 100.00 Using where
我在查询中所做的基本上是构建一个巨大的表(许多联接),然后在这个巨大的表上应用过滤器,我认为这是非常糟糕的做法。
更具体地说,问题是:
如何重写此查询,以便首先将时间筛选器应用于 origins
表,并且只有在 origins
表(仅在与时间筛选器匹配的记录上)?
在第一排 explain
输出,我在下面 row
价值 10699008
,这是mysql需要通过的预期记录数,对吗?如果我理解正确,我应该尝试降低它以获得速度,有没有关于如何做到这一点的最佳实践?
我是否应该对该查询进行其他改进以使其更快?
谢谢。
暂无答案!
目前还没有任何答案,快来回答吧!