大型select-mysql中的索引

大型select-mysql中的索引,mysql,indexing,Mysql,Indexing,我有一个很大的选择,这是一个有点慢,我想一些帮助,以改善它 select c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo, p.youtube, pp.foto, count(DISTINCT likes.user) as likes_count, count(distinct comentarios.id) as comentarios_count, count(DISTINCT l2.user) as count2 from p

我有一个很大的选择,这是一个有点慢,我想一些帮助,以改善它

select c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo, p.youtube, pp.foto, count(DISTINCT likes.user) as likes_count, count(distinct comentarios.id) as comentarios_count, count(DISTINCT l2.user) as count2

from posts p 

join cadastro c on p.user=c.id 
left join profile_picture pp on p.user = pp.user
left join likes on likes.post = p.id
left join comentarios on comentarios.foto = p.id and comentarios.delete = 0  
left join likes l2 on l2.post = p.id and l2.user = ?

where p.user=? and p.delete='0'
group by p.id
order by p.id limit ?
我应该在哪里添加索引以加快我的选择?
打开的所有字段中
在哪里
?比如:
p.user,c.id,pp.user,p.delete
。。。这不是太多了吗?

加速此查询的一个好方法是重构它以进行延迟连接。目标是做你的
选择。。。订购人。。。使用尽可能少的列数限制…
对结果集的操作。为什么这很重要?对大结果集进行排序比对小结果集进行排序成本更高,尤其是当
LIMIT
丢弃大多数排序结果时

因此,从这个子查询开始:

               SELECT p.id, c.id
                 FROM posts p
                 JOIN cadastro c ON p.user=c.id 
                WHERE p.user=? and p.delete='0'
                ORDER BY p.id
                LIMIT ?
这里有用于查询的相关posts.id和cadastro.id值。您可以通过在
上发布(用户,删除)
来加快速度:查询计划器可以通过扫描该复合索引的一部分来完全满足该子查询

然后将其加入到主查询的一个版本中

    SELECT c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo, 
           p.youtube, pp.foto, 
           count(DISTINCT likes.user) as likes_count,
           count(distinct comentarios.id) as comentarios_count,
           count(DISTINCT l2.user) as count2
    FROM (
                   SELECT p.id pid, c.id cid
                     FROM posts p
                     JOIN cadastro c ON p.user=c.id 
                    WHERE p.user=? and p.delete='0'
                    ORDER BY p.id, c.id
                    LIMIT ?
         ) selector
    JOIN posts p ON selector.pid = p.id
    JOIN cadastro c ON selector.cid =  p.user
    left join profile_picture pp on p.user = pp.user
    left join likes on likes.post = p.id
    left join comentarios on comentarios.foto = p.id and comentarios.delete = 0  
    left join likes l2 on l2.post = p.id and l2.user = ?
   where p.user=? and p.delete='0'
   group by p.id
   order by p.id limit ?
您需要按…重做订单
。。。限制?
操作,因为左联接可能会增加最终结果集的大小,您需要限制它

如果没有关于表的更多信息,很难判断哪些索引将加快查询的其余部分。所有这些计数(不同的…)操作都不可避免地有些昂贵。您可能会从以下内容中受益:

专业提示您正在使用,并且可能误用。您的
GROUP BY
应该这样说,否则可能会以不可预测的方式选择
c.nome
c.user
的值

GROUP BY p.id, c.id

Pro-tip单列索引通常对查询或子查询没有多大帮助:MySQL在一个查询中每个表只能使用一个索引。所以,我能帮上大忙。不要只是扔进一堆希望加快查询速度的索引。

加速此查询的一个好方法是重构它以进行延迟连接。目标是做你的
选择。。。订购人。。。使用尽可能少的列数限制…
对结果集的操作。为什么这很重要?对大结果集进行排序比对小结果集进行排序成本更高,尤其是当
LIMIT
丢弃大多数排序结果时

因此,从这个子查询开始:

               SELECT p.id, c.id
                 FROM posts p
                 JOIN cadastro c ON p.user=c.id 
                WHERE p.user=? and p.delete='0'
                ORDER BY p.id
                LIMIT ?
这里有用于查询的相关posts.id和cadastro.id值。您可以通过在
上发布(用户,删除)
来加快速度:查询计划器可以通过扫描该复合索引的一部分来完全满足该子查询

然后将其加入到主查询的一个版本中

    SELECT c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo, 
           p.youtube, pp.foto, 
           count(DISTINCT likes.user) as likes_count,
           count(distinct comentarios.id) as comentarios_count,
           count(DISTINCT l2.user) as count2
    FROM (
                   SELECT p.id pid, c.id cid
                     FROM posts p
                     JOIN cadastro c ON p.user=c.id 
                    WHERE p.user=? and p.delete='0'
                    ORDER BY p.id, c.id
                    LIMIT ?
         ) selector
    JOIN posts p ON selector.pid = p.id
    JOIN cadastro c ON selector.cid =  p.user
    left join profile_picture pp on p.user = pp.user
    left join likes on likes.post = p.id
    left join comentarios on comentarios.foto = p.id and comentarios.delete = 0  
    left join likes l2 on l2.post = p.id and l2.user = ?
   where p.user=? and p.delete='0'
   group by p.id
   order by p.id limit ?
您需要按…重做订单
。。。限制?
操作,因为左联接可能会增加最终结果集的大小,您需要限制它

如果没有关于表的更多信息,很难判断哪些索引将加快查询的其余部分。所有这些计数(不同的…)操作都不可避免地有些昂贵。您可能会从以下内容中受益:

专业提示您正在使用,并且可能误用。您的
GROUP BY
应该这样说,否则可能会以不可预测的方式选择
c.nome
c.user
的值

GROUP BY p.id, c.id

Pro-tip单列索引通常对查询或子查询没有多大帮助:MySQL在一个查询中每个表只能使用一个索引。所以,我能帮上大忙。不要只是为了加快查询速度而添加一堆索引。

post
上添加一个复合索引,顺序如下:

如果我理解“post”和cadastro(注册表),那么每个post都会有一个cadastro条目?因此,不需要在派生表中包含cadastro

此外,我假设每人最多有一个foto。(否则,
groupby
遇到问题,O.Jones将无法得到正确答案。)如果可以有多个,则有一个修复,但您只想显示一个。(使用
MAX

我在
SELECT
子句中使用子查询,以避免
JOIN…groupby
的分解内爆

我不清楚
l2.user=?
的意图,但我没有理会它

SELECT  c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo,
        p.youtube,
        ( SELECT MAX(foto) FROM profile_picture
                           WHERE p.user = user ) AS foto,
        ( SELECT count(DISTINCT user) FROM likes
                           WHERE post = p.id ) as likes_count,
        ( SELECT count(distinct id) FROM comentarios
                           WHERE foto = p.id
                             AND delete  = 0 ) as comentarios_count,
        ( SELECT count(DISTINCT user) FROM likes
                           WHERE post = p.id
                             AND user = ? ) as count2
    FROM  
    (
        SELECT  p.id pid
            FROM  posts p
            WHERE  p.user=?
              and  p.delete='0'
            ORDER BY  p.id
            LIMIT  ? 
    ) selector
    JOIN  posts p  ON selector.pid = p.id
    JOIN  cadastro c  ON p.user = c.id
    ORDER BY  p.id

按以下顺序在
post
上添加复合索引:

如果我理解“post”和cadastro(注册表),那么每个post都会有一个cadastro条目?因此,不需要在派生表中包含cadastro

此外,我假设每人最多有一个foto。(否则,
groupby
遇到问题,O.Jones将无法得到正确答案。)如果可以有多个,则有一个修复,但您只想显示一个。(使用
MAX

我在
SELECT
子句中使用子查询,以避免
JOIN…groupby
的分解内爆

我不清楚
l2.user=?
的意图,但我没有理会它

SELECT  c.nome, p.foto, c.user, p.user, p.id, p.data, p.titulo,
        p.youtube,
        ( SELECT MAX(foto) FROM profile_picture
                           WHERE p.user = user ) AS foto,
        ( SELECT count(DISTINCT user) FROM likes
                           WHERE post = p.id ) as likes_count,
        ( SELECT count(distinct id) FROM comentarios
                           WHERE foto = p.id
                             AND delete  = 0 ) as comentarios_count,
        ( SELECT count(DISTINCT user) FROM likes
                           WHERE post = p.id
                             AND user = ? ) as count2
    FROM  
    (
        SELECT  p.id pid
            FROM  posts p
            WHERE  p.user=?
              and  p.delete='0'
            ORDER BY  p.id
            LIMIT  ? 
    ) selector
    JOIN  posts p  ON selector.pid = p.id
    JOIN  cadastro c  ON p.user = c.id
    ORDER BY  p.id

请看这些。请特别注意有关查询性能的部分。那么请您的问题给我们提供更多信息,以便我们可以帮助您。您的表格中有多少行?您是否计划仅在
limit
中使用此查询,或者这只是分页的第一个示例,以便稍后获得具有偏移量的其他部分?请阅读这些。请特别注意有关查询性能的部分。那么请您的问题给我们提供更多信息,以便我们可以帮助您。您的表格中有多少行?您是否计划仅在
限制
时使用此查询,或者这只是分页的第一个示例,以便稍后获得具有偏移量的其他部分?非常感谢,我将尝试您的提示!帮了我很多。非常感谢你,我会试试你的建议!帮了我很多忙。