我有一个带有权重日志的表,其中包含这些字段(以及其他字段)和示例数据:
userid date weight
---------------------------
1 2015-01-10 100
1 2015-01-15 90
1 2015-01-20 80
2 2015-01-05 120
2 2015-01-15 110
3 2015-01-15 150
3 2015-01-24 140
我需要在日期之间减掉总重量。目前,在 2015-01-09 和 2015-01-21 之间,我在PHP中使用此功能:
function get_weight_loss($userid, $start_date, $end_date) {
global $db;
$query = "
SELECT date, weight FROM weight_tracker_log
WHERE date=(
SELECT MAX(date) FROM weight_tracker_log
WHERE date <= '$start_date' AND userid = $userid
) AND userid = $userid
";
$result = mysql_query($query, $db);
$previous = mysql_fetch_assoc($result);
if ( !$previous['date'] ) {
/* Get first entry for user */
$query = "
SELECT date, weight FROM weight_tracker_log
WHERE date=(
SELECT MIN(date) FROM weight_tracker_log
WHERE userid = $userid
) AND userid = $userid
";
$result = mysql_query($query, $db);
$previous = mysql_fetch_assoc($result);
};
$query = "
SELECT date, weight FROM weight_tracker_log
WHERE date=(
SELECT MAX(date) FROM weight_tracker_log
WHERE date <= '$end_date' AND userid = $userid
) AND userid = $userid
";
$result = mysql_query($query, $db);
$next = mysql_fetch_assoc($result);
mysql_free_result($result);
if ( $previous['date'] && $next['date'] && $previous['date']<$next['date'] && $next['date']>$start_date) {
return $previous['weight'] - $next['weight'];
} else {
return 0;
};
};
它工作正常,但计算越来越长。它的作用是:
$start_date
$start_date
之后查找第一个用户的条目
有没有办法优化查询或算法本身?
该表是以这种方式创建的:
CREATE TABLE `weight_tracker_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL COMMENT 'xcart_cutomers',
`weight` int(11) NOT NULL COMMENT 'grams',
`date` date NOT NULL COMMENT 'YYYY-MM-DD',
`is_start_weight` char(1) NOT NULL DEFAULT 'N',
`is_end_weight` char(1) NOT NULL DEFAULT 'N',
`image` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=97526 DEFAULT CHARSET=utf8
答案 0 :(得分:3)
我没有在你的桌子上看到任何索引。这意味着每个SELECT必须遍历整个表以查找受影响的行。想象一下,如果你不得不翻阅500页书的每一页,只是为了找到与狗有关的两页。
您需要在date
和userid
列添加索引:
CREATE INDEX weight_tracker_log_date ON weight_tracker_log ( date );
CREATE INDEX weight_tracker_log_userid ON weight_tracker_log ( userid );
http://use-the-index-luke.com/是对如何以及为何使用索引的精彩介绍。