如何为我的学校项目优化此查询

时间:2017-08-18 12:57:38

标签: sql oracle mongodb query-optimization

我的任务帮助我优化以下两个查询。

优化作业1:

SELECT 
    n.node_id,
    MIN(LEAST(n.date,ec.date)) date
FROM 
    n, ec
WHERE 
    (n.node_id = ec.node_id_from OR n.node_id = ec.node_id_to)
    AND n.date - ec.date > 0
GROUP BY 
    n.node_id;

优化作业2:

SELECT 
    TO_CHAR(CONVERT_TIMEZONE ('UTC','America/Los_Angeles', tableA."date"), 'YYYY-MM') AS "date_month",
    COUNT(DISTINCT CASE WHEN (tableB."date" IS NOT NULL) THEN tableB._id ELSE NULL END) AS "tableB.countB",
    COUNT(DISTINCT CASE WHEN (tableC."date" IS NOT NULL) THEN tableC._id ELSE NULL END) AS "tableC.countC"
FROM 
    tableA AS tableA
LEFT JOIN 
    tableB AS tableB ON (DATE (CONVERT_TIMEZONE ('UTC', 'America/Los_Angeles',tableB."date"))) = (DATE (CONVERT_TIMEZONE ('UTC', 'America/Los_Angeles',tableA."date")))
LEFT JOIN 
    tableC AS tableC ON (DATE (CONVERT_TIMEZONE ('UTC', 'America/Los_Angeles',tableC."date"))) = (DATE (CONVERT_TIMEZONE ('UTC', 'America/Los_Angeles',tableA."date")))
WHERE 
    tableA."date" >= CONVERT_TIMEZONE ('America/Los_Angeles', 'UTC', DATEADD (month, -17, DATE_TRUNC('month', DATE_TRUNC('day', CONVERT_TIMEZONE ('UTC', 'America/Los_Angeles',GETDATE ()))))
GROUP BY 
    1
ORDER BY 
    1 DESC 
LIMIT 500;

2 个答案:

答案 0 :(得分:1)

分配#1的非常简单的解决方案

SELECT n.node_id, MIN(ec.date) as date
FROM n 
JOIN ec
  ON n.node_id IN (ec.node_id_from, ec.node_id_to) AND ec.date < n.date
GROUP BY n.node_id;

只使用min(ec.date)而不是MIN(LEAST(n.date,ec.date))。 因为JOIN已经迫使ec.date低于n.date。

还要注意像

这样的where子句
where (x >= y and x <= z)

可以更改为

where (x between y and z)

答案 1 :(得分:1)

使用简短的别名,使sql查询更简洁,更清晰。 这是第二个查询的优化版本

SELECT DatePart(month, a.Date-8/24) date_month, 
  sum(case when b.date is Not null then 1 else 0 end) countb,
  sum(case when c.date is Not null then 1 else 0 end) countc,
FROM tableA a    
  LEFT JOIN tableB b 
     ON b.Date = a.Date -- Timezone offsets are not necessary, 
  LEFT JOIN tableC c  
     ON c.date = a.date -- both in same timezone 
WHERE a.date >= DateAdd(hour, 8,
            DATEADD (month,-17,DATE_TRUNC('month', 
             GETDATE () ))
GROUP BY 1
ORDER BY 1 DESC LIMIT 500;