我安装了一个插件,并在后端进行了优化(SSD,对GROUP BY&WHERE中调用的列进行单列索引)但是在运行此查询时
SELECT u.user_id, u.profile_page_id, u.server_id AS user_server_id, u.user_name, u.full_name, u.gender, u.user_image, u.is_invisible, u.user_group_id, u.language_id, u.birthday, u.country_iso, m.*
FROM(
(SELECT m.*
FROM phpfox_channel_video AS m
INNER JOIN phpfox_channel_category AS mc
ON(mc.category_id = mc.category_id)
INNER JOIN phpfox_channel_category_data AS mcd
ON(mcd.video_id = m.video_id)
WHERE m.in_process = 0 AND m.view_id = 0 AND m.module_id = 'videochannel' AND m.item_id = 0 AND m.privacy IN(0) AND mcd.category_id = 17
GROUP BY m.video_id
ORDER BY m.time_stamp DESC
)) AS m
JOIN phpfox_user AS u
ON(u.user_id = m.user_id)
ORDER BY m.time_stamp DESC
LIMIT 24;
需要20秒,而改为更改为此时间
SELECT u.user_id, u.profile_page_id, u.server_id AS user_server_id, u.user_name, u.full_name, u.gender, u.user_image, u.is_invisible, u.user_group_id, u.language_id, u.birthday, u.country_iso, m.*
FROM(
(SELECT m.*
FROM phpfox_channel_video AS m
INNER JOIN phpfox_channel_category_data AS mcd
ON(mcd.video_id = m.video_id AND mcd.category_id = 17)
WHERE m.in_process = 0 AND m.view_id = 0 AND m.module_id = 'videochannel' AND m.item_id = 0 AND m.privacy IN(0)
GROUP BY m.video_id
ORDER BY m.time_stamp DESC
)) AS m
JOIN phpfox_user AS u
ON(u.user_id = m.user_id)
ORDER BY m.time_stamp DESC
LIMIT 24;
此过程大约需要5-6秒
phpfox_channel_video包含200万行(并将继续快速添加,它是一个社交媒体网站,用户也可以上传文件),因此缓存不是很有用(但已激活)。
关于如何优化它的任何提示?我对MariaDB / MySQL的经验最少,因为我已经习惯于使用MS SQL处理大数据并创建自己的结构。无需对表做太多改动的任何推荐方法(添加表即可)。
或者我应该重组PHP&表以将查询优化为低于1秒/查询。谢谢!
我找到了这些链接http://mysql.rjweb.org/doc.php/memory&http://mysql.rjweb.org/doc.php/ricksrots#indexing
它们仍然有用吗?
附上解释结果对于索引,当前配置被设置为索引,每一列都被声明为索引键,上面查询中涉及的所有所有表。
打印当前的服务器配置是否有帮助?谢谢!
我在检查表后设法清理查询,结果证明是这样
WHERE m.in_process = 0 AND m.view_id = 0 AND m.module_id = 'videochannel' AND m.item_id = 0 AND m.privacy IN(0)
不需要运行,因为所有表都符合该条件..(对于本网站的当前情况)。所以我只是优化那些长查询。并且设法击中<1秒..
INNER JOIN phpfox_channel_category AS mc ON(mc.category_id = mc.category_id)
是否几乎没有用。
mc
的任何列用于其他目的。JOIN
。JOIN
验证了mc
中存在相应的行。JOIN
将膨胀临时表。GROUP BY
中的工作浪费。类似地,您的第二个查询不使用mcd
。
请对派生表使用不同的别名。很难遵循m.
的多种用法。
这完全没用:
ORDER BY m.time_stamp DESC
MySQL / MariaDB可以随意忽略派生表中的ORDER BY
。一个表被定义为无序行集合。订购只能在最后完成。
建议索引
m: INDEX(item_id, module_id, view_id, in_process, -- any order; tested with '='
privacy, -- sometimes has a list?
video_id) -- last
mcd: INDEX(category_id, video_id) -- in either order
有一种更合乎逻辑的方法,并且可能更快:
INNER JOIN phpfox_channel_category_data AS mcd
ON mcd.video_id = m.video_id
AND mcd.category_id = 17
删除,然后删除GROUP BY m.id
,然后将其添加到WHERE
:
AND EXISTS( SELECT 1 FROM phpfox_channel_category_data AS mcd
WHERE mcd.video_id = m.video_id
AND mcd.category_id = 17 )
(上述索引仍然适用。)
不是我也许已经消除了两个“文件排序”-GROUP BY
和ORDER BY
。另一个注意事项:EXPLAIN
并不总是显示实际有多少个文件排序。 (但是EXPLAIN FORMAT=JSON SELECT ...
是。)