SQL Select查询与几个子查询优化

时间:2019-05-27 10:13:19

标签: mysql sql

我有带有此类表的MySql数据库:

PageviewEvents:
pageviewId | eventId | eventValue | eventTime

SessionPageviews:
id | sessionId | page 

PageviewEvents.pageviewId是将SessionPageviews.id称为外键。

当我需要通过eventId选择一些数据时,我使用以下查询:

SELECT 
    sp.page as Page, count(*)
from PageviewEvents pe
left join SessionPageviews sp on sp.id = pe.pageviewId
where pe.eventId = 1
GROUP by sp.page
order BY 2 DESC

并获得一个这样的表:

page | count_of_event_1

但是现在我需要选择更多数据:

page | count_of_event_1 | count_of_event_2 ... | count_of_event_N

我从2个事件开始,并尝试白色的东西:

SELECT 
    sp.page as Page, 
    (SELECT count(*) from PageviewEvents pe1 left join SessionPageviews sp1 on sp1.id = pe1.pageviewId where pe1.eventId = 1 and sp1.page = sp.page) as count_of_event_1,
    (SELECT count(*) from PageviewEvents pe1 left join SessionPageviews sp1 on sp1.id = pe1.pageviewId where pe1.eventId = 2 and sp1.page = sp.page) as count_of_event_2 
from PageviewEvents pe
left join SessionPageviews sp on sp.id = pe.pageviewId
where pe.eventId = 1 OR pe.eventId = 2
GROUP by sp.page
order BY 2 DESC

当我在远程服务器上运行此查询时,它冻结。

我的查询中是否有任何错误?如何优化它?

2 个答案:

答案 0 :(得分:2)

您可以尝试使用条件聚合:

SELECT
    sp.page AS Page,
    COUNT(CASE WHEN pe.eventId = 1 THEN 1 END) AS count_of_event_1,
    COUNT(CASE WHEN pe.eventId = 2 THEN 1 END) AS count_of_event_2
FROM PageviewEvents pe
LEFT JOIN SessionPageviews sp
    ON sp.id = pe.pageviewId
WHERE
    pe.eventId IN (1, 2)
GROUP BY
    sp.page
ORDER BY
    2 DESC;

除上述内容外,您还可以考虑在表中添加以下索引:

CREATE INDEX idx ON SessionPageviews (pageviewId, eventId);

这可能有助于加快两个表之间的连接。

答案 1 :(得分:1)

首先,您的查询可疑。您使用的是LEFT JOIN,但是您正在按 second 表中的一列进行汇总。我怀疑您是否真的想在第一列中插入NULL

您可以使用条件聚合(如Tim所指出的)编写查询。我可以这样表示:

select sp.page as Page, 
       sum( pe.eventid = 1 ) as count_of_event_1,
       sum( pe.eventid = 1 ) as count_of_event_2
from SessionPageviews sp join
     PageviewEvents pe
     on sp.id = pe.pageviewId
where pe.eventId in (1, 2)
group by sp.page
order by 2 desc;

然后对于此查询,有两种索引策略。如果您有多种类型的事件(或者1和2相对少见),则:

  • SessionPageviews(id, page)
  • PageviewEvents(eventId, pageviewId)

否则:

  • SessionPageviews(page, id)
  • PageviewEvents(pageviewId, eventId)