Mysql 优化混乱的查询

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

所以我有这个邪恶的查询,需要清理它,因为执行它需要2分钟。我不能改变任何表结构,但我可以把它分成循环中的子查询等。我使用C++和mysql。 基本上是选择标记,然后查询必须选择与标记有联合的任何用户

以下是查询,其中123是长度>=1的CSV标记id列表,而josh@test.com作为要忽略的CSV电子邮件列表,长度>=0。我知道这要求很高,但任何建议都将不胜感激

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,请将您对此的详细回复作为您问题的更新。这样,它就在一个可见的地方,如果适用的话,这个非答案可以在之后安全地删除。谢谢