简体   繁体   English

如何优化SQL查询?

[英]How to optimize the SQL query?

I have an SQL query that I think is not optimized enough. 我有一个SQL查询,我认为不够优化。 I timed it, and it sometimes take 1.5 seconds to complete, which seems a little high, no? 我计时了,有时需要1.5秒才能完成,这似乎有点高,不是吗?

anyway this is the query: 无论如何这是查询:

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

You can rewrite the 4 NOT IN sub queries as one single sub query and since you're grouping by items.title you can even eliminate all sub queries and use joins instead. 您可以将4 NOT IN子查询重写为单个子查询,并且由于您按items.title分组,您甚至可以消除所有子查询并使用连接。

That way whatever you join will be joined only once and you can recreate the various comparisons by grouping them in one bigger logical expression (x = y AND y = z) OR (k = l AND m = n) . 这样,无论你加入什么,你只会加入一次,你可以通过将它们分组成一个更大的逻辑表达式(x = y AND y = z) OR (k = l AND m = n)来重新创建各种比较。

To most effectively optimize queries, you should start by identifying the queries that have the longest duration. 要最有效地优化查询,您应该首先确定持续时间最长的查询。 You can do so by using SQL Profiler. 您可以使用SQL事件探查器来完成此操作。 Next, you analyze the queries to determine where they are spending their time and whether they can be improved. 接下来,您将分析查询以确定他们花费时间的位置以及是否可以对其进行改进。 You can use the SQL Query Analyzer to help analyze query behavior. 您可以使用SQL查询分析器来帮助分析查询行为。

The overall optimization process consists of two main steps: 整个优化过程包括两个主要步骤:

1) Isolate long-running queries. 1)隔离长时间运行的查询。

2) Identify the cause of long-running queries. 2)确定长时间运行查询的原因。

Step 1 第1步

  • You can isolate long-running queries using SQL Profiler. 您可以使用SQL事件探查器隔离长时间运行的查询。

Step 2 第2步

  • Using SET statements. 使用SET语句。
  • Using SQL Query Analyzer options. 使用SQL查询分析器选项。

To use SQL Query Analyzer 使用SQL查询分析器

SQL Query Analyzer displays query execution plans in text mode or graphical mode. SQL查询分析器以文本模式或图形模式显示查询执行计划。

1) Start SQL Query Analyzer, connect to the server, and select the database that you are working on. 1)启动SQL查询分析器,连接到服务器,然后选择您正在处理的数据库。

2) Paste the query into the SQL Query Analyzer window. 2)将查询粘贴到SQL查询分析器窗口中。

3) If you are using SQL Profiler to trace queries, the query text can be copied from the trace window and used within SQL Query Analyzer. 3)如果使用SQL事件探查器跟踪查询,则可以从跟踪窗口复制查询文本并在SQL查询分析器中使用。

4) On the Query menu, click Display Estimated Execution Plan . 4)在“ 查询”菜单上,单击“ 显示估计执行计划” The estimated execution plan for the query is displayed. 将显示查询的估计执行计划。 If the query window contains multiple queries, an execution plan is displayed for each query. 如果查询窗口包含多个查询,则会为每个查询显示执行计划。

5) On the Query menu, click Show Execution Plan , and then run the query in the query window.Execution plans and query results now appear in separate panes of the window so you can view them together. 5)在“ 查询”菜单上,单击“ 显示执行计划” ,然后在查询窗口中运行查询。执行计划和查询结果现在显示在窗口的单独窗格中,以便您可以一起查看它们。

I hope that this will help you! 我希望这会对你有所帮助!

Regards, 问候,

Nicholas 尼古拉斯

I tried to minimize 4 Not In queries in where condition. 我试图在where条件下最小化4 Not In查询。 Can you see this works or not? 你能看到这个有用吗?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM