1

我有一个我认为不够优化的 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
4

3 回答 3

2

您可以将 4 个子查询重写NOT IN为一个子查询,并且由于您正在分组,items.title您甚至可以消除所有子查询并改用联接。

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

于 2012-08-16T12:41:20.017 回答
1

为了最有效地优化查询,您应该首先确定持续时间最长的查询。您可以使用 SQL 事件探查器来执行此操作。接下来,您分析查询以确定它们将时间花在哪里以及是否可以改进它们。您可以使用 SQL 查询分析器来帮助分析查询行为。

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

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

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

步骤1

  • 您可以使用 SQL Profiler 隔离长时间运行的查询。

第2步

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

使用 SQL 查询分析器

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

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

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

3) 如果您使用 SQL Profiler 跟踪查询,则可以从跟踪窗口复制查询文本并在 SQL Query Analyzer 中使用。

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

5) 在Query菜单上,单击Show Execution Plan,然后在查询窗口中运行查询。执行计划和查询结果现在显示在窗口的不同窗格中,因此您可以一起查看它们。

我希望这会对你有所帮助!

问候,

尼古拉斯

于 2012-08-16T14:06:46.357 回答
0

我试图在 where 条件下最小化 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
于 2012-08-16T12:58:32.443 回答