我还可以做些什么来优化此查询?
SELECT * FROM
(SELECT `item`.itemID, COUNT(`votes`.itemID) AS `votes`,
`item`.title, `item`.itemTypeID, `item`.
submitDate, `item`.deleted, `item`.ItemCat,
`item`.counter, `item`.userID, `users`.name,
TIMESTAMPDIFF(minute,`submitDate`,NOW()) AS 'timeMin' ,
`myItems`.userID as userIDFav, `myItems`.deleted as myDeleted
FROM (votes `votes` RIGHT OUTER JOIN item `item`
ON (`votes`.itemID = `item`.itemID))
INNER JOIN
users `users`
ON (`users`.userID = `item`.userID)
LEFT OUTER JOIN
myItems `myItems`
ON (`myItems`.itemID = `item`.itemID)
WHERE (`item`.deleted = 0)
GROUP BY `item`.itemID,
`votes`.itemID,
`item`.title,
`item`.itemTypeID,
`item`.submitDate,
`item`.deleted,
`item`.ItemCat,
`item`.counter,
`item`.userID,
`users`.name,
`myItems`.deleted,
`myItems`.userID
ORDER BY `item`.itemID DESC) as myTable
where myTable.userIDFav = 3 or myTable.userIDFav is null
limit 0, 20
我正在使用MySQL
由于
答案 0 :(得分:9)
分析器对此查询说了什么?如果不了解表中有多少行,就无法进行任何优化。因此,运行分析仪,您将看到哪些部分成本是多少。
答案 1 :(得分:5)
当然,正如@theomega所说,看看执行计划。
但我也建议尝试“清理”你的陈述。 (我不知道哪一个更快 - 这取决于你的表大小。)通常,我会尝试从一个干净的语句开始并从那里开始优化。但通常情况下,一个干净的语句使优化器更容易提出一个好的执行计划。
所以这里有一些关于你的陈述的观察可能会让事情变得缓慢:
据我了解你的SQL,这个陈述应该完成你的大部分工作:
SELECT `item`.itemID, `item`.title, `item`.itemTypeID, `item`.
submitDate, `item`.deleted, `item`.ItemCat,
`item`.counter, `item`.userID, `users`.name,
TIMESTAMPDIFF(minute,`submitDate`,NOW()) AS 'timeMin'
FROM (item `item` INNER JOIN users `users`
ON (`users`.userID = `item`.userID)
在哪里
当然,这会错过您加入的表中的信息,我建议尝试通过子选择添加所需的列:
SELECT `item`.itemID,
(SELECT count (itemID)
FROM votes v
WHERE v.itemID = 'item'.itemID) as 'votes', <etc.>
这样,您可以删除一个外部联接和组。外部联接由子选择替换,因此存在权衡,这可能对“清洁”声明不利。
根据item和myItems之间的基数,您可以执行相同操作,或者您必须坚持使用外连接(但不需要重新引入组)。
希望这有帮助。
答案 2 :(得分:1)
一些快速的半随机想法:
您的itemID和userID列是否已编入索引?
如果在查询开头添加“EXPLAIN”并运行它会发生什么?它是否使用索引?他们是明智的吗?
您是否需要运行整个内部查询并对其进行过滤,或者您是否可以将where myTable.userIDFav = 3 or myTable.userIDFav is null
部分移动到内部查询中?
答案 3 :(得分:0)
你似乎在Group By列表中有太多字段,因为其中一个是itemID,我怀疑你可以使用内部SELECT来预先形成分组,而外部SELECT则返回所需的字段集。 / p>
答案 4 :(得分:0)
你不能将where子句 myTable.userIDFav = 3或myTable.userIDFav为空添加到 WHERE(item
。deleted = 0)?
问候
利芬
答案 5 :(得分:0)
查看构建查询的方式。你加入了很多东西,然后将输出限制为20行。您应该在项目和myitems上具有外部联接,因为您的条件仅适用于这两个表,将输出限制为前20行,然后加入和聚合。在这里,你正在完成许多将被丢弃的工作。