当前位置:  开发笔记 > 后端 > 正文

优化SQL查询

如何解决《优化SQL查询》经验,为你挑选了2个好方法。

我还可以做些什么来优化此查询?

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

谢谢



1> theomega..:

分析器对此查询说了什么?如果没有关于表格中有多少行的知识,您就无法进行任何优化.因此,运行分析仪,您将看到哪些部件成本.



2> Thorsten..:

当然,正如@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', 

这样,您可以删除一个外连接和组.外连接由子选择替换,因此存在权衡,这可能对"清洁"语句不利.

根据item和myItems之间的基数,您可以执行相同操作,或者您必须坚持使用外连接(但不需要重新引入组).

希望这可以帮助.

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有