TIMESTAMPDIFF MIN MAX优化

时间:2017-02-01 23:14:48

标签: mysql join query-performance

我有3张Innodb表2其中“大”

  • composer_sessions 92行
  • 会话2,530,587行
  • 跟踪8,032,697行

我正在运行以下查询:

SELECT TIMESTAMPDIFF(SECOND,
                     MIN(tracking.timestamp),
                     MAX(tracking.timestamp) ) AS `thetime`,
       SUM(tracking.type = 'scene') AS `scenecount` 
FROM `tracking`, `sessions` 
WHERE tracking.tour_ID = '102098'
  AND sessions.session_ID = tracking.session_ID 
  AND sessions.IP NOT IN(SELECT DISTINCT `IP`
                          FROM `composer_sessions`)
GROUP BY tracking.session_ID
HAVING TIMESTAMPDIFF(SECOND, MIN(tracking.timestamp), 
                             MAX(tracking.timestamp)) <= '3600'
   AND TIMESTAMPDIFF(SECOND, MIN(tracking.timestamp),
                             MAX(tracking.timestamp) ) > '60'
   AND SUM(tracking.type = 'scene') >= '2'

查询中使用的所有列都已编制索引。 查询中的“连接”用于清除与结果中不需要的IP地址关联的数据。

我是否有更好的方法来构建此查询和/或任何人都可以建议复合(多列)索引来使此查询运行得更快?

1 个答案:

答案 0 :(得分:1)

尝试调整查询以使用现代连接语法,例如

SELECT ...
  FROM tracking
  JOIN sessions ON sessions.session_ID = tracking.session_ID
  LEFT JOIN composer_sessions ON sessions.IP = composer_sessions.IP
 WHERE composer_sessions.IP IS NULL
   AND tracking.tour_ID = '102098'
 GROUP BY tracking.session_ID
HAVING ...

这也使用LEFT JOIN ... IS NULL模式根据第三个表的内容消除不需要的行。

然后,在tracking表格上创建一个所谓的compound covering index。它应按此顺序包含以下列。

    ( tour_id, session_id, timestamp, type )

这允许直接从索引中满足查询的tracking部分。查询计划程序可以根据您选择的tour_id随机访问索引,因为该值在索引中是最左侧的。然后它可以按顺序扫描索引以提取您需要的其他内容。

同样,在<{p>}上的sessions表上尝试复合索引

   ( session_ID, IP )

看看它是否有帮助。您也可以尝试以相反的顺序放置这些列。

请注意,各列上的大量索引很少有助于复杂查询的性能。你需要精心挑选的复合指数。许多单列索引通常被认为对整体性能有害,因为它们会减慢插入和更新速度并且不会带来任何好处。

阅读本文:http://use-the-index-luke.com/