Ако имате индекс с created
като водеща колона, MySQL може да е в състояние да направи обратно сканиране. Ако имате 24-часов период, който няма събития, може да връщате ред, който НЕ е от този период. За да сте сигурни, че получавате ред през този период, наистина ще трябва да включите долна граница на created
колона също, нещо подобно:
SELECT * FROM `eventos`
WHERE ...
AND `created` < FROM_UNIXTIME( {$timestamp} )
AND `created` >= DATE_ADD(FROM_UNIXTIME( {$timestamp} ),INTERVAL -24 HOUR)
ORDER BY `created` DESC
LIMIT 1
Мисля, че големият ключ към производителността тук е индекс с created
като водеща колона, заедно с всички (или повечето) други колони, посочени в клаузата WHERE, и се уверете, че индексът се използва от вашата заявка.
Ако имате нужда от различен интервал от време, до втория, този подход може лесно да бъде обобщен.
SELECT * FROM `eventos`
WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL 0*{$nsecs} SECOND)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -1*{$nsecs} SECOND)
ORDER BY `created` DESC
LIMIT 1
От вашия код изглежда, че 24-часовите периоди са ограничени в произволно време... ако функцията за време връща напр. 1341580800 ('2012-07-06 13:20'), тогава всичките ви десет цикъла ще бъдат от 13:20 на даден ден до 13:20 на следващия ден.
(ЗАБЕЛЕЖКА:уверете се, че ако параметърът ви е цяло число с времеви клеймо на unix, това се интерпретира правилно от базата данни.)
Може да е по-ефективно да издърпате десетте реда в една заявка. Ако има гаранция, че 'timestamp' е уникален, тогава е възможно да се създаде такава заявка, но текстът на заявката ще бъде значително по-сложен от този, който имате сега. Можем да се забъркаме с получаването на MAX(timestamp_) в рамките на всеки период и след това да го присъединим обратно, за да получим реда... но това ще бъде наистина объркано.
Ако щях да се опитам да изтегля всичките десет реда, вероятно щях да опитам да използвам UNION ALL
подход, не е много красив, но поне може да бъде настроен.
SELECT p0.*
FROM ( SELECT * FROM `eventos` WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL 0*24 HOUR)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -1*24 HOUR)
ORDER BY `created` DESC LIMIT 1
) p0
UNION ALL
SELECT p1.*
FROM ( SELECT * FROM `eventos` WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -1*24 HOUR)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -2*24 HOUR)
ORDER BY `created` DESC LIMIT 1
) p1
UNION ALL
SELECT p2.*
FROM ( SELECT * FROM `eventos` WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -2*24 HOUR)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -3*24 HOUR)
ORDER BY `created` DESC LIMIT 1
) p2
UNION ALL
SELECT p3.*
FROM ...
Отново, това може да бъде обобщено, за да премине за няколко секунди като аргумент. Заменете HOUR със SECOND и заменете „24“ с параметър за свързване, който има брой секунди.
Това е доста дълго, но трябва да работи добре.
Друг наистина разхвърлян и сложен начин да върнете това обратно в един набор от резултати би бил да използвате вграден изглед, за да получите крайната дата за време за десетте периода, нещо подобно:
SELECT p.period_end
FROM (SELECT DATE_ADD(t.t_,INTERVAL -1 * i.i_* {$nsecs} SECOND) AS period_end
FROM (SELECT FROM_UNIXTIME( {$timestamp} ) AS t_) t
JOIN (SELECT 0 AS i_
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
) i
) p
И след това присъединете това към вашата маса ...
ON `created` < p.period_end
AND `created` >= DATE_ADD(p.period_end,INTERVAL -1 * {$nsecs} SECOND)
И издърпайте MAX(създадено) за всеки период GROUP BY p.period_end, увийте това във вграден изглед.
И след това присъединете това обратно към вашата таблица, за да получите всеки ред.
Но това е наистина, наистина объркано, трудно за разбиране и едва ли ще бъде по-бързо (или по-ефективно) от това, което вече правите. Най-голямото подобрение, което бихте могли да направите, е времето, необходимо за изпълнение на 9 от вашите заявки.