更高效的sql查询

时间:2017-01-09 01:23:58

标签: mysql query-optimization

这些是我的一些查询工作得很好但是现在当桌子有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地理位置

2 个答案:

答案 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之后我可以说更多。