优化乱码查询

时间:2011-07-18 18:02:10

标签: 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
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)

编辑:以下是EXPLAIN的结果,为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"

2 个答案:

答案 0 :(得分:2)

与实际答案相反,但更详细的问题澄清...你的内部查询似乎在查询(在这里解释)

SystemTag_Union表中包含一个或多个列出的标记的任何用户ID,但不同标记的计数= 0。

这听起来像个傻瓜...给我一些有这些标签的东西,但是标签的数量= 0 ......就是这样......为了符合资格,必须有一个满足WHERE子句。

您能澄清一下这次查询的最终意图吗?您是否正在尝试寻找那些可能(或没有)与您相关的特定标签的用户?

我实际上会将查询更改为使用不同的

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' )

答案 1 :(得分:0)

所以我最终做的是双重的。我添加了索引并重新优化了我的表,这有点帮助,然后我完全提取了systemtag子查询,并将其存储在一个变量中,然后我将其插入到更大的查询中。即使子查询只花了0.2秒,它也必须在20k用户数据库的每次迭代中执行。非常感谢大家,你的指导是不可或缺的。