Mysql 更高效的sql查询

Mysql 更高效的sql查询,mysql,query-optimization,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` = ?

这些是我的一些查询,它们工作得很好,但是现在当表有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);
(预计行数还会增加,我能得到服务器端的建议/更改吗?)

编辑:

以下是更新表的查询

$REVICTION=$db->getRow(“从
”中选择traffic\u id
”。前缀。“traffic\u stats
,其中
key
=?s和
ip地址
=?s和
domain`=?s”,“$key$ip,$domain”)

`
对于ip地理位置也有一些优化,一个优化是使用一个查询,而不是三个查询:

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 |
+---------------------+---------------------+

由于所有(?)查询都基于
userid
,并且表将非常大,因此可能需要有一个以
userid
开始的集群
主键
,并可能创建
。在您提供
SHOW CREATE TABLE

之后,我可以说更多。您有哪些索引?关于优化的问题总是需要,至少需要为所有相关表创建表语句,并解释结果。此外,请参见一个明显的优化,即反转日期(from_unixtime(created))=当前日期的逻辑,以便对常量而不是column@Strawberry我编辑了关于它的问题,谢谢。@PM 77-1,我不确定,我认为没有。谢谢你的回答,但我需要在不同的地方分别回应这些问题,我如何才能用一个问题做到这一点?@Naby,在你回复我的第一条评论之前,我们没有什么可以补充的了。@Naby,在这种情况下,你一定是看错了或忽略了附在我原始评论后面的已接受的答案。
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 |
+---------------------+---------------------+