所以我有这个不圣洁的查询,需要清理它,因为执行需要大约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"
答案 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用户数据库的每次迭代中执行。非常感谢大家,你的指导是不可或缺的。