Mysql 优化混乱的查询
所以我有这个邪恶的查询,需要清理它,因为执行它需要2分钟。我不能改变任何表结构,但我可以把它分成循环中的子查询等。我使用C++和mysql。 基本上是选择标记,然后查询必须选择与标记有联合的任何用户 以下是查询,其中123是长度>=1的CSV标记id列表,而josh@test.com作为要忽略的CSV电子邮件列表,长度>=0。我知道这要求很高,但任何建议都将不胜感激Mysql 优化混乱的查询,mysql,performance,database-optimization,Mysql,Performance,Database Optimization,所以我有这个邪恶的查询,需要清理它,因为执行它需要2分钟。我不能改变任何表结构,但我可以把它分成循环中的子查询等。我使用C++和mysql。 基本上是选择标记,然后查询必须选择与标记有联合的任何用户 以下是查询,其中123是长度>=1的CSV标记id列表,而josh@test.com作为要忽略的CSV电子邮件列表,长度>=0。我知道这要求很高,但任何建议都将不胜感激 SELECT user_id,user_primaryemail,USER_EMAIL_IS_VALID FROM users W
SELECT user_id,user_primaryemail,USER_EMAIL_IS_VALID
FROM users
WHERE ( ( user_id IN ( SELECT union_target_id
FROM systemtag_union
WHERE union_systemtag_id IN ( '123' )
&& union_type = 'User'
GROUP BY union_target_id
HAVING COUNT(DISTINCT union_systemtag_id) = 0) ) )
&& user_primaryemail NOT IN ( 'josh@test.com' )
&& USER_EMAIL_IS_VALID != 'No'
GROUP BY user_primaryemail
粗略表格结构:
users
-----
user_id
user_primaryemail
user_email_is_valid
systemtags
-----
systemtag_id
systemtag_union
-----
union_systemtag_id (corresponds to systemtags.systemtag_id)
union_target_id (corresponds, in this case, to users.user_id)
union_type (the type of the union, irrelevant in this case)
编辑:以下是解释的结果,作为CSV:
"id","select_type","table","type","possible_keys","key","key_len","ref","rows","Extra"
1,"PRIMARY","users","ALL","user_email","","","",9104,"Using where; Using temporary; Using filesort"
2,"DEPENDENT SUBQUERY","systemtag_union","index","union_systemtag_id,union_type","union_target_id","4","",8,"Using where"
与实际答案相反,更详细的问题澄清。。。您的内部查询似乎正在查询(此处进行解释) SystemTag_Union表中具有一个或多个列出的标记的任何用户ID,但不同标记的计数=0 这听起来像是自相矛盾的说法。。。给我一些有这些标签之一的东西,但是标签的数量=0。。。哪一个是。。。为了获得资格,必须有一个符合WHERE条款的 你能澄清一下这个查询的最终目的是什么吗?您是否试图寻找那些可能(或不可能)有特定标签的用户,您将根据这些标签采取行动 实际上,我会将查询更改为使用distinct,例如
SELECT DISTINCT
U.user_id,
U.user_primaryemail,
U.USER_EMAIL_IS_VALID
FROM
users U
JOIN systemtag_union STU
ON U.User_ID = STU.union_target_id
AND STU.Union_Type = 'User'
AND STU.union_systemtag_id IN ( '123' )
WHERE
U.USER_EMAIL_IS_VALID != 'No'
AND U.user_primaryemail NOT IN ( 'josh@test.com' )
所以我最终做了两件事。我添加了索引并重新优化了我的表,这有点帮助,然后我完全提取了systemtag子查询,并将其存储在一个变量中,然后将其插入到更大的查询中。尽管子查询只花了.2秒,但它一定是在20k用户数据库的每次迭代中执行的。非常感谢你们,你们的指导是不可或缺的 您在数据库中的任何表都被索引了吗?能否请您分享这些表是如何被索引的,以及
解释选择…
的结果?那将非常有帮助。谢谢。就像暗中捅一刀一样,我希望拥有COUNT(DISTINCT…)。这个短语将在运行查询时强制执行大量的物化和排序。@Paul:user\u id、systemtag\u id和未列出的union\u id都是唯一的autoinc主键。@Josh Yep<代码>解释{query}
将给出执行计划(它将如何加入、将使用什么键等)。正如您所说,这不是一个完整的答案(但对于注释来说太长)。所以@Josh,请将您对此的详细回复作为您问题的更新。这样,它就在一个可见的地方,如果适用的话,这个非答案可以在之后安全地删除。谢谢