目前,我正在开展一个项目,该项目要求我为用户编写API。到目前为止,我已经编写了以下SQL语句,并在我的本地主机上通过我的php进行了测试:
SELECT topquery.kind_id,
topquery.image,
topquery.id,
userquery.user_name
FROM `order` AS topquery,
`user` AS userquery
WHERE userquery.user_id = topquery.user_id
AND topquery.id IN
(SELECT MIN(id)
FROM `order` AS mainquery
WHERE user_id != '$vUserId'
AND id NOT IN
(SELECT order_id
FROM history
WHERE user_id = '$vUserId')
AND kind_id NOT IN
(SELECT o.kind_id
FROM history h
INNER JOIN `order` o ON h.order_id = o.id
WHERE h.user_id = '$vUserId')
AND actions > 0
AND kind = '1'
GROUP BY kind_id)
ORDER BY vip DESC
LIMIT 35
此查询在我的本地主机上大约需要0.5秒,在我的服务器上需要大约1.4秒。
现在我的问题: 是否有可能SQL查询的速度因每个mysql版本而异? 或者我的查询不是"优化"足够?
答案 0 :(得分:0)
是的,它会有所不同,因为每个版本的sql都有不同的调整要优化或代码路径或算法处理速度。我认为最新版本会比之前版本更快。
答案 1 :(得分:0)
关闭主题建议,但我想要格式化以便评论不够
您可以使用where子句
中的连接谓词开始查询FROM `order` AS topquery,
`user` AS userquery
WHERE userquery.user_id = topquery.user_id
在查询的更深层次中,您确实使用INNER JOIN语法。那么为什么不一直这样做呢?
FROM `order` AS topquery,
INNER JOIN `user` AS userquery ON userquery.user_id = topquery.user_id
坚持只使用显式连接。不允许自己在from子句中的表之间使用逗号。不要"混合搭配"加入语法,这会导致维护问题和可能的错误。
答案 2 :(得分:0)
在这里,我概述了您的案例的诊断,然后您可以确定速度是否仍然是一个问题:
网络。我不确定那个时间是纯粹是从SQL执行还是网络时间也在那里。您的网络电话会产生开销。
这取决于您的服务器是什么,但如果您的环境匹配,几乎总是肯定的,因为您的服务器数据库中的数据远多于您的本地主机。
在公司环境中拥有共享开发服务器的一个优点是,有人可能会经常为您提供一些数据,因此每个人都不必将所有数据复制到他们的计算机上以使用实际大小数据集。更多数据=更多工作=需要更长时间,更简单。
您的数据库架构存在差异。如果您不能在一个命令中重建数据库,则可能在localhost上添加了索引并忘记了它。您可以使用模式工具来获取localhost和数据库之间的差异。我喜欢SQLYog。我认为Mysql工作台也是这样做的。
您的硬件存在差异。即你的服务器是486,内存为4mb。
答案 3 :(得分:0)
服务器之间的性能差异
是的,性能可以在不同的MySQL版本之间变化。原因是整个软件可能会发生变化,包括MySQL优化器,它会计算查询将执行的计划。
在决定MySQL版本是否是根本原因之前,我会检查的几个因素是:
查询效果
此外,我查看了您的查询,看起来可以更好地进行优化。
(我使用EverSQL SQL Query Optimizer来获取建议 - 免责声明,我是EverSQL的联合创始人并谦虚地提供这些建议):
这是优化后查询的样子:
create table temp as
SELECT
o.kind_id
FROM
history h
INNER JOIN `order` o ON h.order_id = o.id
WHERE
h.user_id = '$vUserId';
CREATE INDEX kind_id on temp(kind_id);
create table temp2 as
SELECT
MIN(id) as id
FROM
`order` AS mainquery
left join history h on mainquery.id=h.order_id
left join temp t on mainquery.kind_id=t.kind_id
WHERE
user_id != '$vUserId'
AND h.order id is null
and t.kind_id is null
AND actions > 0
AND kind = '1'
GROUP BY
kind_id;
CREATE INDEX id on temp2(id);
SELECT
topquery.kind_id,
topquery.image,
topquery.id,
userquery.user_name
FROM
`order` AS topquery,
`user` AS userquery,
temp2 AS temp
WHERE
userquery.user_id = topquery.user_id
AND topquery.id = temp.id
ORDER BY vip DESC
LIMIT 35