TIMESTAMPDIFF MIN MAX 优化
TIMESTAMPDIFF MIN MAX optimization
我有 3 个 Innodb 表,其中 2 个是 "large"
- 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'
查询中使用的所有列都已编入索引。
查询中的 "join" 用于清除与结果中不需要的 IP 地址相关的数据。
我有没有更好的方法来构造这个查询and/or谁能建议复合(多列)索引来使这个查询运行更快?
尝试调整您的查询以使用现代连接语法,例如
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
模式根据第三个 table 的内容消除不需要的行。
然后,在您的 tracking
table 上创建一个 so-called compound covering index。它应按此顺序包含以下列。
( tour_id, session_id, timestamp, type )
这允许直接从索引中满足查询的 tracking
部分。查询计划器可以根据您选择的 tour_id
random-access 索引,因为该值在索引中是 left-most。然后它可以按顺序扫描索引以提取您需要的其余内容。
同样,在
sessions
table 上尝试复合索引
( session_ID, IP )
看看是否有帮助。您也可以尝试将这些列按相反的顺序排列。
请注意,单个列上的大量索引很少有助于复杂查询的性能。为此,您需要 well-chosen 个复合索引。许多 single-column 索引通常被认为对整体性能有害,因为它们会减慢插入和更新速度并且没有任何好处。
我有 3 个 Innodb 表,其中 2 个是 "large"
- 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'
查询中使用的所有列都已编入索引。 查询中的 "join" 用于清除与结果中不需要的 IP 地址相关的数据。
我有没有更好的方法来构造这个查询and/or谁能建议复合(多列)索引来使这个查询运行更快?
尝试调整您的查询以使用现代连接语法,例如
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
模式根据第三个 table 的内容消除不需要的行。
然后,在您的 tracking
table 上创建一个 so-called compound covering index。它应按此顺序包含以下列。
( tour_id, session_id, timestamp, type )
这允许直接从索引中满足查询的 tracking
部分。查询计划器可以根据您选择的 tour_id
random-access 索引,因为该值在索引中是 left-most。然后它可以按顺序扫描索引以提取您需要的其余内容。
同样,在
sessions
table 上尝试复合索引
( session_ID, IP )
看看是否有帮助。您也可以尝试将这些列按相反的顺序排列。
请注意,单个列上的大量索引很少有助于复杂查询的性能。为此,您需要 well-chosen 个复合索引。许多 single-column 索引通常被认为对整体性能有害,因为它们会减慢插入和更新速度并且没有任何好处。