这些是我的一些查询工作得很好但是现在当桌子有500万行时,这些查询的时间很长,可以加载大约30秒。
并且允许内存运行这些设置为500 mb如果我将内存设置为400 mb,页面会因为内存耗尽而出错,这些查询会说出这么多时间和内存。
如何使这些SQL查询更有效?
$total_traffic = $db->getAll("SELECT COUNT(`userid`) AS `total_clicks` FROM `".PREFIX."traffic_stats` WHERE `userid` = ?i", $user->data->userid);
$total_earning = $db->getAll("SELECT SUM(`rate`) AS `total_earned` FROM `".PREFIX."traffic_stats` WHERE `userid` = ?i", $user->data->userid);
$today_earning = $db->getAll("SELECT SUM(`rate`) AS `today_earned` FROM `".PREFIX."traffic_stats` WHERE `userid` = ?i AND DATE(from_unixtime(created)) = CURRENT_DATE ORDER BY created DESC", $user->data->userid);
$yesterday_earning = $db->getAll("SELECT SUM(`rate`) AS `yesterday_earned` FROM `".PREFIX."traffic_stats` WHERE `userid` = ?i AND DATE(from_unixtime(created)) = DATE_SUB(CURRENT_DATE,INTERVAL 1 DAY) ORDER BY created DESC", $user->data->userid);
(并且预计行数会增加更多是否有任何服务器端建议/更改?)
编辑:
这是更新表的查询
$revisit = $db->getRow("SELECT
traffic_id FROM
" .PREFIX。" traffic_stats WHERE
密钥= ?s AND
ip_address = ?s AND
domain` =?s",$ key,$ ip,$ domain);
$traffic_data = array(
"userid" => $userid,
"username" => $username,
"article_id" => $article,
"key" => $key,
"domain" => $domain,
"origin" => $origin,
"ip_address" => $ip,
"rate" => $rate,
"created" => $time
);
if(!$revisit) {
if(($db->query("INSERT INTO `".PREFIX."traffic_stats` SET ?u", $traffic_data)) && ($id = $db->insertId())) {
if(($db->query("UPDATE `".PREFIX."articles` SET `viewed` = `viewed` + ?i WHERE `article_id` = ?i", 1, $article)) && ($db->query("UPDATE `".PREFIX."user_stats` SET `clicked` = `clicked` + ?i WHERE `article_id` = ?i AND `key` = ?s", 1, $article, $key))) {
echo json_encode(array("status" => 1, "url" => $redirect_url, "title" => $get_redirect->article_title, "desc" => $get_redirect->article_desc, "domain" => $track->domain.$key, "base_domain" => $track->domain, "image" => $get_redirect->article_og_image));
}
}
` 并且还有一些用于ip地理位置
答案 0 :(得分:1)
一个优化是使用一个查询而不是三个:
SELECT COUNT(userid) total_clicks
, SUM(rate) total_earned
, SUM(CASE WHEN DATE(from_unixtime(created)) = CURRENT_DATE THEN rate END) total_earned_today
, SUM(CASE WHEN DATE(from_unixtime(created)) = CURRENT_DATE - INTERVAL 1 DAY THEN rate END) total_earned_yesterday
FROM traffic_stats
WHERE userid = $userid
如需进一步优化,请参阅上面的评论,但这是另一件需要考虑的事情......
SELECT CURDATE();
+------------+
| CURDATE() |
+------------+
| 2017-01-09 |
+------------+
SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP()/86400)*86400) x
, FROM_UNIXTIME(CEILING(UNIX_TIMESTAMP()/86400)*86400) y;
+---------------------+---------------------+
| x | y |
+---------------------+---------------------+
| 2017-01-09 00:00:00 | 2017-01-10 00:00:00 |
+---------------------+---------------------+
答案 1 :(得分:0)
由于您的所有(?)查询都基于userid
,并且该表格非常大,因此可能需要以PRIMARY KEY
开头的群集userid
created
。在您提供SHOW CREATE TABLE
之后我可以说更多。