Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.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
Sql 优化需要1分钟执行的简单查询_Sql_Mysql_Query Optimization - Fatal编程技术网

Sql 优化需要1分钟执行的简单查询

Sql 优化需要1分钟执行的简单查询,sql,mysql,query-optimization,Sql,Mysql,Query Optimization,我有一个相当简单的SQL查询,但执行它几乎需要一分钟: SELECT i.id, ..., a.id AS albums_id, ..., u.id AS users_id, ... FROM images i LEFT JOIN albums a ON i.albums_id = a.id LEFT JOIN users u ON a.users_id = u.id WHERE a.access = 'public' AND i.num_of_views > 0

我有一个相当简单的SQL查询,但执行它几乎需要一分钟:

SELECT
 i.id,
 ...,
 a.id AS albums_id,
 ...,
 u.id AS users_id,
 ...
FROM
 images i
  LEFT JOIN albums a ON i.albums_id = a.id
  LEFT JOIN users u ON a.users_id = u.id
WHERE
 a.access = 'public'
 AND i.num_of_views > 0
ORDER BY
 i.num_of_views DESC
LIMIT
 0, 60
上述查询的解释结果:

涉及的表格:

图像
(~4822000行)、
相册
(~149000行)、
用户
(~43000行)

相关指标:

相册
:访问(访问,图片数量,相册时间),访问2(访问,图片数量,所有评论数量,相册时间),用户id(用户id,相册时间)

图像
:浏览器2(视图数量),相册id(相册id,图像顺序)

所有选项卡都是InnoDB,运行在MySql v5.1.47上

那我怎么才能把它降到一秒钟以下呢

如果您需要任何其他信息,请留下评论

编辑:
用户
表格可以加入
相册
图像
对我来说无关紧要


edit2:moving
a.access='public'
from
WHERE
to
JOIN
确实解决了我的问题,但返回的结果不正确(我从非公共相册中获取图像),将
a.access…
同时放在
WHERE
JOIN
中,查询速度会比以前慢得多。

相册上添加索引。用户id
。我也同意关于
a.access='public'
的评论。但不管怎样,该指数都会有所帮助

更新 因为上面的密钥存在。尝试调整您的
加入的顺序
,即在相册上方移动
用户
,或将不同的表作为主要表。在极少数情况下,这会有所帮助。另外,要更好地加入相册,请尝试:

LEFT JOIN albums a ON (i.albums_id = a.id AND a.access = 'public')
更新 根据这些评论,我将尽可能多地删除
左连接。由于我不确定您在结果中需要什么,我将只在
相册中显示它。这不仅可以减少结果集,而且可以解决应用过滤器的问题

JOIN albums a ON (i.albums_id = a.id AND a.access = 'public')

在相册上添加索引。用户id
。我也同意关于
a.access='public'
的评论。但不管怎样,该指数都会有所帮助

更新 因为上面的密钥存在。尝试调整您的
加入的顺序
,即在相册上方移动
用户
,或将不同的表作为主要表。在极少数情况下,这会有所帮助。另外,要更好地加入相册,请尝试:

LEFT JOIN albums a ON (i.albums_id = a.id AND a.access = 'public')
更新 根据这些评论,我将尽可能多地删除
左连接。由于我不确定您在结果中需要什么,我将只在
相册中显示它。这不仅可以减少结果集,而且可以解决应用过滤器的问题

JOIN albums a ON (i.albums_id = a.id AND a.access = 'public')

根据您最近的评论,您应该使用相册的内部连接,而不是左连接

SELECT
 i.id,
 ...,
 a.id AS albums_id,
 ...,
 u.id AS users_id,
 ...
FROM images i
  INNER JOIN albums a ON i.albums_id = a.id
  LEFT JOIN users u ON a.users_id = u.id
WHERE a.access = 'public'
 AND i.num_of_views > 0
ORDER BY i.num_of_views DESC
LIMIT 0, 60

根据您最近的评论,您应该使用相册的内部连接,而不是左连接

SELECT
 i.id,
 ...,
 a.id AS albums_id,
 ...,
 u.id AS users_id,
 ...
FROM images i
  INNER JOIN albums a ON i.albums_id = a.id
  LEFT JOIN users u ON a.users_id = u.id
WHERE a.access = 'public'
 AND i.num_of_views > 0
ORDER BY i.num_of_views DESC
LIMIT 0, 60

我相信这里有一点混乱,即过滤器对左连接和内部连接的影响

Jan,如果您试图在查询中询问的是“获取所有公开相册的所有图像,并获取这些相册的用户”,那么您不需要左连接,而是需要内部连接。左连接将返回所有相册的所有图像,但也将返回没有匹配相册的所有图像。您可以添加“且a.id不为NULL”,但这与内部联接相同

我相信你想要的是:

SELECT
 i.id,
 ...,
 a.id AS albums_id,
 ...,
 u.id AS users_id,
 ...
FROM images i
  INNER JOIN albums a ON i.albums_id = a.id AND a.access = 'public'
  INNER JOIN users u ON a.users_id = u.id
WHERE i.num_of_views > 0
ORDER BY i.num_of_views DESC
LIMIT 0, 60

如果将“加入相册”留给用户,则可以返回所有没有用户的相册。不确定您想要哪一个。

我相信这里有一点混乱,即筛选器对左连接和内部连接的影响

Jan,如果您试图在查询中询问的是“获取所有公开相册的所有图像,并获取这些相册的用户”,那么您不需要左连接,而是需要内部连接。左连接将返回所有相册的所有图像,但也将返回没有匹配相册的所有图像。您可以添加“且a.id不为NULL”,但这与内部联接相同

我相信你想要的是:

SELECT
 i.id,
 ...,
 a.id AS albums_id,
 ...,
 u.id AS users_id,
 ...
FROM images i
  INNER JOIN albums a ON i.albums_id = a.id AND a.access = 'public'
  INNER JOIN users u ON a.users_id = u.id
WHERE i.num_of_views > 0
ORDER BY i.num_of_views DESC
LIMIT 0, 60


如果将“加入相册”留给用户,则可以返回所有没有用户的相册。不确定你想要哪一个。

你确定你得到了正确的结果吗?在where子句中引用
a.access
的事实否定了相册上的左连接,并有效地将其转换为内部连接。如果确实需要左连接,那么
a.access='public'
应该是连接条件的一部分。@Joe Stefanelli我是通过albums的主键(a.id=I.albums\u id)连接的,我如何才能将
a.access='public'
放入其中?顺便说一句,结果是正确的。请不要在格式化代码中使用制表符text@OMG小马修好了,我可以问一下原因吗?您的加入条件将变成
…在I.albums\u id=a.id和a.access='public'…
上左加入相册a您确定得到了正确的结果吗?在where子句中引用
a.access
的事实否定了相册上的左连接,并有效地将其转换为内部连接。如果确实需要左连接,那么
a.access='public'
应该是连接条件的一部分。@Joe Stefanelli我是通过albums的主键(a.id=I.albums\u id)连接的,我如何才能将
a.access='public'
放入其中?顺便说一句,结果是正确的。请不要在格式化代码中使用制表符text@OMG小马修好了,我可以问一下为什么吗?你的加入条件将变成
…在I.albums\u id=a.id和a.access='public'上左加入相册a…
对不起,我忘了提到我有那个索引,请参阅我的更新。在标准中不需要括号。@OMG,明白了。只是个人习惯而已,切赫!这将查询时间缩短到0.0016秒:)我是一个我认识的白痴:)该死,应该让我的评论成为一个答案!:-)对不起,我忘了提到我有那个索引,请看我的更新