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