【发布时间】:2012-07-22 23:22:52
【问题描述】:
好的,一些入门;我是专家级的 PHP/JS/C 开发人员,但一直无法全面掌握 MySQL。如果你能回答我的问题,那就太好了,但如果你能指出我的好资源的方向,以了解复杂的 MySQL 查询的注意事项(主要是从效率的角度来看),那将同样有帮助)。
目标
我需要在单个表中找到相似之处/重叠,同时仍然提取整个结果集(与另一个表中的实际标题/描述内容进行 LEFT JOIN)。
表格极其简单;它包含 3 列(page、user、time)。
基本上每个查询将有两个用户。我需要提取匹配User 1 的所有结果的计数、匹配User 2 的所有结果的计数以及重叠的所有列(加上左连接)(其中User 1 和User 2 在表中都有匹配项.
示例查询
此查询有效,但速度极慢(到了需要几分钟才能运行的程度),而且我猜测由于子查询而效率低下。如果任何 SQL 专家能指出一种更有效的方法来做到这一点(以及为什么),将不胜感激。
SELECT DISTINCT `page`,
(SELECT COUNT(*) FROM `m_likes` WHERE `user` = "1") AS userLikes,
(SELECT COUNT(*) FROM `m_likes` WHERE `user` = "2") AS friendLikes
FROM `m_likes` LEFT JOIN `app_pages` AS page ON (page.id = `page`)
WHERE `page` IN (SELECT `page` FROM `m_likes` WHERE `user` = "1")
AND `page` IN (SELECT `page` FROM `m_likes` WHERE `user` = "2")
AND (`user` = "1" OR `user` = "2")
解释查询结果
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m_likes index NULL page 604 NULL 35043 Using where; Using index; Using temporary
1 PRIMARY page eq_ref PRIMARY PRIMARY 767 tablename.m_likes.page 1
5 DEPENDENT SUBQUERY m_likes unique_subquery page page 604 func,const 1 Using index; Using where
4 DEPENDENT SUBQUERY m_likes unique_subquery page page 604 func,const 1 Using index; Using where
3 SUBQUERY m_likes index NULL page 604 NULL 35043 Using where; Using index
2 SUBQUERY m_likes index NULL page 604 NULL 35043 Using where; Using index
表架构
app_pages:idVARCHAR(255)、nameVARCHAR(255)、categoryVARCHAR(255)
m_likes:pageVARCHAR(255)、userVARCHAR(255)、timeINT(20)
m_likes.page = app_pages.id
另外值得注意的是,不幸的是,用户和页面 ID 必须是 VARCHAR 而不是 INT,因为不能保证这可以在 64 位系统上运行,并且某些 ID 值大于允许的最大值32 位系统...希望这不会对性能造成重大影响。
输出示例
array (size=156)
0 =>
array (size=6)
'page' => string '100861973286778' (length=15)
'time' => string '1297383617' (length=10)
'name' => string 'Leila' (length=5)
'category' => string 'Book' (length=4)
'userLikes' => string '104' (length=3)
'friendLikes' => string '52' (length=2)
1 =>
array (size=6)
'page' => string '10150160788195604' (length=17)
'time' => string '1272653871' (length=10)
'name' => string 'Frisbee Golfing' (length=15)
'category' => string 'Interest' (length=8)
'userLikes' => string '104' (length=3)
'friendLikes' => string '52' (length=2)
【问题讨论】:
-
使用EXPLAIN 更好地了解 MySQL 如何执行您的查询
-
我已经尝试过使用 EXPLAIN 但坦率地说它并没有那么有用;该查询完全按照我的预期执行,但它并没有让我了解如何更好地设计它,而这正是我希望 SQL 专家能够做到的。
-
你能把结果贴在这里吗?
-
@Julian,如果您发布表架构(
m_likes和app_pages中的列),我们会更容易解读您的问题 -
解释有问题的结果; cmets 中的格式问题。添加了表架构。
标签: mysql sql database-design