![](/img/trans.png)
[英]Can't get my query to run any faster on MySQL database with 2M entries
[英]Can't run specific SQL query on my database
我有一个聊天应用程序数据库。
CREATE TABLE Users (uid int PRIMARY KEY, name text, phone text );
CREATE TABLE Messages (recipient int REFERENCES Users(uid), sender int
REFERENCES Users(uid), time timestamp NOT NULL, message text NOT NULL,
PRIMARY KEY (recipient, sender, time));
http://www.sqlfiddle.com/#!9/bd36d1
我想为发送最多消息的5个用户中的每个用户定义该用户发送的消息的平均长度。
我写了以下查询:
SELECT avg(strlen(message))
FROM Messages
WHERE sender IN
(SELECT *
FROM (SELECT sender, COUNT(sender) AS NumberOfMessages
FROM Messages
GROUP BY sender) AS MessagesPerSender
ORDER BY NumberOfMessages DESC
LIMIT 5)
首先,此查询正确吗? 它给我想要的结果吗? 问题是我根本无法运行它,原因是出现错误:
“此版本的MySQL尚不支持'LIMIT&IN / ALL / ANY / SOME子查询”
对于mysql这可能不是正确的方法
select sender,avg(length(message)),count(*)
from messages
group by sender
order by avg(length(message)) desc limit 5;
+--------+----------------------+----------+
| sender | avg(length(message)) | count(*) |
+--------+----------------------+----------+
| 1 | 9.0000 | 1 |
| 9 | 5.5000 | 2 |
| 2 | 5.0000 | 1 |
+--------+----------------------+----------+
3 rows in set (0.00 sec)
请注意,这可能无法以您想要的方式处理抽奖。
您的代码中有2个错误:
首先,您不能在MYSQL中使用strlen
。 那是Microsoft SQL Server的方言,您需要使用length
。
其次,在您使用的子查询中,您使用的是两列。 这将导致查询失败,因为equals运算符仅需要等于一列中的值。
因此,这是您的查询:
select u.name, avg(length(m.message)), count(*)
from Messages m
inner join Users u on m.sender = u.uid
group by u.name
order by avg(length(m.message)) desc limit 5;
由于我为您提供了发件人的姓名而非他们的ID,因此我改进了P. Salmon的回答。
希望这可以帮助 :)
为了找出答案,我将DMBS从MySQL更改为支持内部限制的Postgres。 您的查询语法正确,但strlen()
函数除外,正确的语法是length()
。
但是,查询失败的原因很简单: where sender in (subquery)
中执行where sender in (subquery)
,尽管您的子查询返回两个字段。 in
运算符仅适用于单字段查询。 而且,您的子查询由两个查询组成,可以简化为一个查询。 以下查询适用于Postgres 9.6,并且应适用于具有内部限制支持的任何版本的MySQL:
SELECT avg(length(message))
FROM Messages
WHERE sender IN (
SELECT sender
FROM Messages
GROUP BY sender
ORDER BY COUNT(sender) DESC
LIMIT 5
)
在样本数据上运行时,它将产生以下结果:
+----------+
| avg |
+----------+
| 6.25 |
+----------+
工作中的SQL Fiddle(Postgres 9.6): http ://www.sqlfiddle.com/#!17 / bd36d / 6/0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.