3

我的工作之一是维护我们的数据库,通常我们在获取报告和在该基础上工作时会遇到性能不足的问题。
当我开始查看我们的 ERP 发送到数据库的查询时,我在主查询中看到了很多完全不必要的子选择查询。
由于我不是我们使用的程序的创建者开发人员的成员,所以当我批评他们的代码和工作时,他们不太喜欢。假设他们不将我的评论视为严肃的陈述。所以我问你几个关于 SQL 中的子选择的问题

子选择是否比左外连接花费更多时间?
是否存在任何博客、文章或我推荐不使用的任何内容?
我如何证明如果我们在查询中避免 subselectesct 查询会更快?

我们的数据库服务器是 MSSQL2005

4

6 回答 6

5

“Show, Don't Tell” - 检查并比较使用 SQL Profiler 识别的查询的查询计划。特别注意表扫描和书签查找(您希望尽可能频繁地查看索引搜索)。查询计划的“拟合优度”取决于最新的统计数据、定义的索引、整体查询工作量。

在 SQL Server Management Studio (SSMS) 中运行查询并打开 Query->Include Actual Execution Plan (CTRL+M)

认为自己很幸运,它们只是子选择(在某些情况下,优化器会产生等效的“加入计划”)而不是相关的子查询!

识别一个执行大量逻辑读取的查询,使用您喜欢的技术重写它,然后通过比较显示它执行的逻辑读取量有多少。

这里有一个提示。要获得执行的逻辑读取总数,请使用以下命令包装有问题的查询:

SET STATISTICS IO ON
GO

-- Run your query here

SET STATISTICS IO OFF
GO

运行查询,然后切换到结果窗格中的消息选项卡。

如果您有兴趣了解更多信息,没有比SQL Server 2008 Query Performance Tuning Distilled更好的书了,它涵盖了监视、解释和修复性能问题的基本技术。

于 2010-12-28T12:34:33.257 回答
2

您可以做的一件事是加载 SQL Profiler 并向他们显示子查询的成本(在 CPU 周期、读取和写入方面)。很难与冷酷的统计数据争论。

我还将检查这些查询的查询计划,以确保使用了适当的索引,并且将表/索引扫描保持在最低限度。

一般来说,如果使用正确并且有适当的索引,我不会说子查询不好。

于 2010-12-28T12:33:09.677 回答
1

我对 MSSQL 不是很熟悉,因为我们在大多数应用程序中都使用 postrgesql。但是应该存在类似“EXPLAIN”的东西,它向您显示查询的执行计划。在那里,您应该能够看到查询将产生的各种步骤以检索所需的数据。

如果您看到有很多表扫描或循环连接而没有使用任何索引,这绝对是查询执行缓慢的提示。使用这样的工具,您应该能够比较两个查询(一个有连接,另一个没有)

很难说哪种方法更好,因为它实际上高度依赖于优化器在各种情况下可以采用的索引,并且根据 DBMS,优化器可能能够隐式地将子查询重写为连接查询和执行它。

如果你真的想展示哪个更好,你必须同时执行并测量时间、cpu 使用率等。

更新:可能是 MSSQL 的这个——> QueryPlan

于 2010-12-28T12:41:15.650 回答
1

根据我自己的经验,这两种方法都是有效的,例如 EXISTS 子选择可以避免大量的早期中断处理。

但大多数时候,带有大量子选择的查询是由并不真正了解 SQL 并使用他们经典的过程式程序员思考查询的开发人员完成的。然后他们甚至不考虑连接,并提出一些糟糕的查询。所以我更喜欢连接,而且我总是检查子查询。老实说,我跟踪慢查询,我对包含子选择的慢查询的第一次尝试是尝试进行连接。工作很多时间。

但是没有规则可以确定子选择比连接差或慢,只是糟糕的 sql 程序员经常做子选择:-)

于 2010-12-28T12:43:20.353 回答
1

子选择是否比左外连接花费更多时间?

这取决于子选择和左外连接。

通常,此构造:

SELECT  *
FROM    mytable
WHERE   mycol NOT IN
        (
        SELECT  othercol
        FROM    othertable
        )

比这有效:

SELECT  m.*
FROM    mytable m
LEFT JOIN
        othertable o
ON      o.othercol = m.mycol
WHERE   o.othercol IS NULL

看这里:

是否存在推荐不使用子选择的任何博客、文章或任何内容?

我会避开盲目推荐避免子选择的博客。

它们的实现是有原因的,不管你信不信,开发人员已经付出了一些努力来优化它们。

How I can prove that if we avoid subselesct in query that query is going to be faster ?

Write a query without the subselects which runs faster.

If you post your query here we possibly will be able to improve it. However, a version with the subselects may turn out to be faster.

于 2010-12-28T16:30:55.460 回答
0

尝试重写一些查询以消除子选择和比较运行时。

分享和享受。

于 2010-12-28T12:59:58.393 回答