MySQL匹配来自同一个表的列

时间:2012-07-22 23:22:53

标签: mysql sql database-design

好一点入门;我是一名专家的PHP / JS / C开发人员,但从来没有能够全面掌握MySQL。如果你能回答我的问题会很棒,但如果你能指出我在良好的资源的方向上了解复杂的MySQL查询做什么和不做什么(主要是从效率的角度来看),那就太有用了)。

目标

我需要在单个表中找到相似性/重叠,同时仍然拉动整个结果集(使用另一个表中的实际标题/描述内容进行LEFT JOIN)。

桌子非常简单;它包含3列(pageusertime)。

基本上每个查询都有两个用户。我需要提取匹配User 1的所有结果的计数,匹配User 2的所有结果的计数和重叠的所有列(加上LEFT JOIN)(其中User 1和{{1在表格中有一个匹配。

示例查询

这个查询有效,但速度非常慢(运行需要几分钟),而且由于子查询,我猜测效率低下。如果任何SQL专家可以指出一种更有效的方法(以及为什么),那将非常感激。

User 2

EXPLAIN查询结果

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

表架构

app_pages 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 VARCHAR(255),id VARCHAR(255),name VARCHAR(255)

m_likes category VARCHAR(255),page VARCHAR(255),user INT(20)

m_likes.page = app_pages.id

另外值得注意的是,不幸的是用户&页面ID必须是VARCHAR而不是INT,因为无法保证在64位系统上运行,并且某些ID值大于32位系统上允许的最大值...希望不会t增加了一个重要的性能。

输出示例

time

1 个答案:

答案 0 :(得分:1)

您的查询运行速度这么慢的原因是因为您正在执行四个单独的子查询,这些子查询实际上最终会执行 EACH 行。

相反,您可以使用子选择的笛卡尔积来获得计数(仅执行一次):

SELECT a.page, c.userLikes, c.friendLikes
FROM m_likes a
INNER JOIN app_pages b ON a.page = b.id
CROSS JOIN
(
    SELECT
        COUNT(CASE WHEN user = '1' THEN 1 END) AS userLikes,
        COUNT(CASE WHEN user = '2' THEN 1 END) AS friendLikes
    FROM m_likes
    WHERE user IN ('1','2')
) c
WHERE a.user IN ('1','2')
GROUP BY a.page
HAVING COUNT(1) = 2

此查询将检索用户1和2都喜欢的所有页面,以及他们喜欢的总计数(将在结果集中重复)。