Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.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子查询优化?_Mysql_Sql_Subquery_Query Optimization_Query Performance_Greatest N Per Group - Fatal编程技术网

Mysql子查询优化?

Mysql子查询优化?,mysql,sql,subquery,query-optimization,query-performance,greatest-n-per-group,Mysql,Sql,Subquery,Query Optimization,Query Performance,Greatest N Per Group,我可以以任何不同的方式使用此代码以获得更好的性能吗 我试过这样做 SELECT K.id, M.m_id, K.Sil, K.Banli, K.Foto, K.KullaniciAdi, K.Ad, K.Soyad, K.Gender, (select rate_id,Rate,Zaman from ratings where UyeID=K.id ORDER BY rate_id DESC LIMIT 1) 但我不能做我想做的事 这是工作代码。给出我想要的结果: SELECT K.id, M

我可以以任何不同的方式使用此代码以获得更好的性能吗

我试过这样做

SELECT K.id, M.m_id, K.Sil, K.Banli, K.Foto, K.KullaniciAdi, K.Ad, K.Soyad, K.Gender,
(select rate_id,Rate,Zaman from ratings where UyeID=K.id ORDER BY rate_id DESC LIMIT 1)
但我不能做我想做的事

这是工作代码。给出我想要的结果:

SELECT K.id, M.m_id, K.Sil, K.Banli, K.Foto, K.KullaniciAdi, K.Ad, K.Soyad, K.Gender,
       (  SELECT R.mr_id FROM mesajlarreply R 
          WHERE R.CID=M.m_id 
          ORDER BY R.mr_id DESC LIMIT 1
       ) as mr_id,
       (  SELECT R.Mesaj FROM mesajlarreply R 
          WHERE R.CID=M.m_id 
          ORDER BY R.mr_id DESC LIMIT 1
       ) as Mesaj,
       (  SELECT R.KayitZaman FROM mesajlarreply R 
          WHERE R.CID=M.m_id 
          ORDER BY R.mr_id DESC LIMIT 1
       ) as KayitZaman
FROM mesajlar M, kullanicilar K
WHERE
     CASE
         WHEN M.K1 =  '1'  THEN M.K2 = K.id
         WHEN M.K2 =  '1'  THEN M.K1 = K.id
     END
   AND ( M.K1 =  '1'  OR M.K2 =  '1' )
ORDER BY M.m_id DESC 
LIMIT 20

假设子查询的顺序应该是相同的,而不是打字错误,那么三者的组合就是一个问题。MySQL有几种现有的解决方案,如果每个组的行数较少,我想我更喜欢中的样式,对于您的情况,这种样式如下所示:

SELECT rToUse.mr_id, rToUse.mesaj, rToUse.kayitZaman
FROM Mesajlarreply rToUse
LEFT JOIN Mesajlarreply rKnockout
       ON rKnockout.cId = rToUse.cId AND rToUse.mr_id < rKnockout.mr_id
WHERE rKnockout.mr_id IS NULL
SELECT K.id, M.m_id, K.sil, K.banli, K.foto, K.kullaniciAdi, K.ad, K.soyad, K.gender,
       R.mr_id, r.mesaj, r.kayitZaman
FROM Mesajlar M
JOIN Kullanicilar K
  ON  (M.k1 = '1' AND M.k2 = K.id) 
      OR (M.k2 = '1' AND M.k1 = K.id)
LEFT JOIN (SELECT rToUse.cId, rToUse.mr_id, rToUse.mesaj, rToUse.kayitZaman
           FROM Mesajlarreply rToUse
           LEFT JOIN Mesajlarreply rKnockout
                  ON rKnockout.cId = rToUse.cId 
                     AND rToUse.mr_id < rKnockout.mr_id
           WHERE rKnockout.mr_id IS NULL) R
       ON R.cId = M.m_id
ORDER BY M.m_id DESC
LIMIT 20
。。。我假设你不存在k1和k2同时等于'1'的情况,所以m.k1'1'是不必要的,如果这是真的,它将保留案例的语义。请注意,ORs仍然可能是性能难点。同样,如果这些列中的任何一列实际上是某种数字类型,那么连接将首先需要转换,这可能会降低性能

因此,我可能会从以下内容开始编写查询:

SELECT rToUse.mr_id, rToUse.mesaj, rToUse.kayitZaman
FROM Mesajlarreply rToUse
LEFT JOIN Mesajlarreply rKnockout
       ON rKnockout.cId = rToUse.cId AND rToUse.mr_id < rKnockout.mr_id
WHERE rKnockout.mr_id IS NULL
SELECT K.id, M.m_id, K.sil, K.banli, K.foto, K.kullaniciAdi, K.ad, K.soyad, K.gender,
       R.mr_id, r.mesaj, r.kayitZaman
FROM Mesajlar M
JOIN Kullanicilar K
  ON  (M.k1 = '1' AND M.k2 = K.id) 
      OR (M.k2 = '1' AND M.k1 = K.id)
LEFT JOIN (SELECT rToUse.cId, rToUse.mr_id, rToUse.mesaj, rToUse.kayitZaman
           FROM Mesajlarreply rToUse
           LEFT JOIN Mesajlarreply rKnockout
                  ON rKnockout.cId = rToUse.cId 
                     AND rToUse.mr_id < rKnockout.mr_id
           WHERE rKnockout.mr_id IS NULL) R
       ON R.cId = M.m_id
ORDER BY M.m_id DESC
LIMIT 20
当然,未经测试-未提供数据集
我对子查询使用了左连接来保留给定的数据语义。如果所有案例都有行,或者只关心那些有行的案例,那么可以将其更改为内部联接。根据数据集的布局方式以及您有/没有的索引,这可能不会有更好的效果,但通常对优化器来说应该更友好。

您可以发布这两个表的结构吗?或者至少请附加有关主键主键的信息-这两个表中哪些列是主键?您的编辑使其看起来像是一个新的/不同的查询。如果是这样,您应该能够根据新的查询调整我的答案;如果你被卡住了,就发一个新问题。@ClockworkMuse我发了一个新问题,但没人帮我。我该怎么做@traBolicEM-因为你还没有表现出你所面临的新问题。你似乎希望我们为你做所有的事情,甚至是小的修改。你应该能够根据你的新问题修改我现有的答案;如果您的问题中有拼写错误,我很乐意调整我的答案,但如果您更改了表或其他列,我们希望您能够处理您的更改。如果我的回答中的表现不足以回答这个问题,那么在这里发布更多细节,比如你有什么指数,解释计划的结果,以获得更好的/额外的帮助。