如何优化SQL查询?

时间:2012-08-16 12:34:22

标签: mysql sql query-optimization

我有一个我认为不够优化的SQL查询。我计时了,有时需要1.5秒才能完成,这似乎有点高,不是吗?

无论如何这是查询:

SELECT id, link, feed, category, description, title, GROUP_CONCAT( tag ) as t, published
            FROM items
            LEFT JOIN tags ON items.id = tags.item_id
            WHERE id NOT IN (
                SELECT item_id
                FROM tags, sinunim
                WHERE tag = name
                AND op = '1'
                AND user = '$user_cookie'
            ) AND id NOT IN (
                SELECT id
                FROM sinunim
                WHERE id <> 0
                AND user = '$user_cookie'
            ) AND id NOT IN (
                SELECT i.id
                FROM  sinunim s, items i
                WHERE s.type =  'category'
                AND s.name = i.category
                AND s.op = '1'
                AND s.user = '$user_cookie'
            ) AND id NOT IN (
                SELECT i.id
                FROM  `sinunim` s, items i
                WHERE s.name = i.feed
                AND s.op = '1'
                AND s.user = '$user_cookie'
            )
            GROUP BY items.title
            ORDER BY items.published DESC
            LIMIT 0 , 50

3 个答案:

答案 0 :(得分:2)

您可以将4个NOT IN子查询重写为一个单个子查询,并且由于您按items.title进行分组,因此您甚至可以消除所有子查询并使用联接。

这样,无论你加入什么,只会加入一次,你可以通过将它们分组在一个更大的逻辑表达式(x = y AND y = z) OR (k = l AND m = n)中来重新创建各种比较。

答案 1 :(得分:1)

要最有效地优化查询,您应首先确定持续时间最长的查询。您可以使用SQL事件探查器来完成此操作。接下来,您将分析查询以确定他们花费时间的位置以及是否可以对其进行改进。您可以使用SQL查询分析器来帮助分析查询行为。

整体优化过程包括两个主要步骤:

1)隔离长时间运行的查询。

2)确定长时间运行查询的原因。

第1步

  • 您可以使用SQL事件探查器隔离长时间运行的查询。

第2步

  • 使用SET语句。
  • 使用SQL查询分析器选项。

使用SQL查询分析器

SQL查询分析器以文本模式或图形模式显示查询执行计划。

1)启动SQL查询分析器,连接到服务器,然后选择您正在使用的数据库。

2)将查询粘贴到SQL查询分析器窗口中。

3)如果使用SQL事件探查器跟踪查询,则可以从跟踪窗口复制查询文本,并在SQL查询分析器中使用。

4)在查询菜单上,点击显示估算执行计划。将显示查询的估计执行计划。如果查询窗口包含多个查询,则会为每个查询显示执行计划。

5)在查询菜单上,单击显示执行计划,然后在查询窗口中运行查询。执行计划和查询结果现在显示在单独的窗格中窗口,以便您可以一起查看它们。

我希望这会对你有帮助!

此致

尼古拉斯

答案 2 :(得分:0)

我尝试在条件有限的情况下最小化4 Not In查询。你能看到这个有用吗?

SELECT id, link, feed, category, description, title, GROUP_CONCAT( tag ) as t, published
            FROM items
            LEFT JOIN tags ON items.id = tags.item_id
            WHERE id NOT IN (
                SELECT case 
                        when ( tag = name AND op = '1' ) then item_id
                        when id <> 0 then id
                       END   
                FROM tags, sinunim
                WHERE user = '$user_cookie'
            )
            AND id NOT IN (
                SELECT i.id
                FROM  sinunim s, items i
                WHERE ( (s.type =  'category'
                AND s.name = i.category) OR s.name = i.feed)  
                AND s.op = '1' 
                AND s.user = '$user_cookie'
            ) 
            GROUP BY items.title
            ORDER BY items.published DESC
            LIMIT 0 , 50