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-因为你还没有表现出你所面临的新问题。你似乎希望我们为你做所有的事情,甚至是小的修改。你应该能够根据你的新问题修改我现有的答案;如果您的问题中有拼写错误,我很乐意调整我的答案,但如果您更改了表或其他列,我们希望您能够处理您的更改。如果我的回答中的表现不足以回答这个问题,那么在这里发布更多细节,比如你有什么指数,解释计划的结果,以获得更好的/额外的帮助。