Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL查询改进(Tmp表、发送数据和排序)_Mysql_Performance - Fatal编程技术网

MySQL查询改进(Tmp表、发送数据和排序)

MySQL查询改进(Tmp表、发送数据和排序),mysql,performance,Mysql,Performance,我的查询如下所示: SELECT Sender, Recipient, Sent FROM (SELECT Sender, Recipient, Sent FROM prv_chat WHERE 100 IN (Sender, Recipient)) AS chat GROUP BY Sender, Recipient ORDER BY Sent DESC LIMIT 30 其目的是搜索特定用户(在本例中为ID为100的用户)发送或接收的所有聊天信息(内部

我的查询如下所示:

    SELECT Sender, Recipient, Sent 
FROM 
     (SELECT Sender, Recipient, Sent FROM prv_chat WHERE 100 IN (Sender, Recipient)) 
     AS chat 
GROUP BY Sender, Recipient 
ORDER BY Sent DESC LIMIT 30
其目的是搜索特定用户(在本例中为ID为100的用户)发送或接收的所有聊天信息(
内部查询)

此查询在我的服务器上运行非常频繁,并且占用了大量时间(
>0.1s

phpMyAdmin分析工具显示,
复制到tmp表
(我猜这是由内部查询引起的),
发送数据
(缺少索引?)占用了约32%的时间,
排序结果

描述
查询告诉我它没有使用任何索引(尽管它说有可能的索引)

以下是完整的列表:

有人有线索吗

编辑:

SHOW CREATE TABLE prv_chat

CREATE TABLE `prv_chat` (
 `ID` int(11) NOT NULL AUTO_INCREMENT,
 `Sender` int(9) NOT NULL,
 `Recipient` int(9) NOT NULL,
 `Chat` text NOT NULL,
 `Sent` datetime NOT NULL,
 `Read` tinyint(1) NOT NULL,
 PRIMARY KEY (`ID`),
 KEY `Sender` (`Sender`,`Recipient`),
 KEY `Sent` (`Sent`),
 KEY `Sender_3` (`Sender`,`Recipient`,`Sent`),
 KEY `Sender_2` (`Sender`,`Sent`),
 KEY `Recipient` (`Recipient`)
) ENGINE=MyISAM AUTO_INCREMENT=125082 DEFAULT CHARSET=utf8
EDIT2:我编辑了查询,现在删除了
排序结果部分。
虽然
发送结果
复制到tmpo表
的过程仍然需要花费大量时间

EDIT3:再次更改了查询。现在唯一占用大量时间的部分是发送数据
描述
返回以下内容:

编辑4:
为Xint0的查询描述

运算符
使mysql忽略索引。请尝试:

SELECT * FROM(
    SELECT *  FROM prv_chat WHERE Sender=100 
    UNION ALL
    SELECT *  FROM prv_chat WHERE Recipient=100 
) AS chat
ORDER BY Sent DESC LIMIT 30; --done by hand, may not run

编辑:查询设计中的逻辑错误。为子查询提供新建议

SELECT *
FROM prv_chat 
WHERE 100 IN (Sender, Recipient) 
ORDER BY Sent DESC;
这应该适用于您当前检索的内容

100 IN(发送者,接收者)
位还将使用您的
Sender\u 3


编辑:您可能还想查看表的
InnoDB
引擎

正如您在注释中所指出的,问题是使用
*
选择所有列。一般建议,如果不需要,尽量不要选择所有列

我建议:

select Sender, Recipient, MaxSent
from (
    select pc.Sender, pc.Recipient, max(pc.Sent) as MaxSent
    from
        prv_chat pc
        inner join (
            select ID from prv_chat where Sender = 100
            union
            select ID from prv_chat where Recipient = 100
        ) f on pc.ID = f.ID
    group by pc.Sender, pc.Recipient
) g
order by MaxSent desc limit 100;
这样子查询
f
会按发件人和收件人过滤ID,并使用相应的索引

然后子查询
g
按发件人、收件人分组并获取最大发送值,应使用索引Sender\u 3

外部查询仅对筛选结果和分组结果排序

编辑

在看到
descripe
输出后,
g
子查询似乎没有使用
Sender\u 3
索引。我建议首先运行
analyze table prv\u chat
命令更新索引统计信息,以便MySQL引擎可以基于当前索引覆盖率优化查询。如果这不会导致引擎使用
Sender\u 3
索引,则尝试修改它以将
ID
作为第一列:
(ID,Sender,Recipient,Sent)

EDIT2


我认为临时表和文件排序是由于对聚合结果进行排序造成的。

您可以发布
prv\u chat
的DDL吗?我将其添加到了第一篇博文中谢谢,这样就消除了排序结果的大部分。但是我在
发送数据
(现在是90%)和
复制到tmp表
表的行数和这个查询的行数没有限制方面仍然有问题。你能对查询运行descripe并发布结果吗?哦,好吧,这似乎对排序部分也起作用。事实上,我不知道为什么在编写查询时需要这个内部查询,但是没有它它就无法工作。但是你的解决方案也能解决这个问题!但是,当我现在尝试按
发送者、接收者对其进行分组时,查询速度又慢了很多(复制到tmp表)。为什么要分组?因为您的查询多次返回相同的发送者-接收者组合。我需要的是最新发送的
不同的(发送者,接收者)
在这种情况下,我建议使用
WHERE 100 In(发送者,接收者)
而不是初始的
语句,并将其用作子查询tank you,此查询似乎工作得很好:),性能也更好。不过,
复制到tmp表
大约需要0.04秒以上的时间。有什么想法吗?--我会马上发布此查询的
描述
结果谢谢,我尝试了两个新建议,但没有改变任何东西。查询仍未使用索引
Sender_3