首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >这些查询中哪一个对性能最好?

这些查询中哪一个对性能最好?
EN

Database Administration用户
提问于 2013-11-01 16:50:25
回答 4查看 5.3K关注 0票数 2

这些查询中哪一个对性能最好?有时,我想知道短脚本是否真的是最好的关注对象。这些脚本执行相同的任务。使用左联接,我只需几行就可以实现我想要的结果。但后来我尝试了一个更长的脚本,使用工会。哪一种是最好的方法?两者之间:

代码语言:javascript
运行
复制
SELECT p.productID, p.product, C.color, C.colorID, S.size, S.sizeID, q.qty From quantities q
        INNER join products P ON p.productID = q.productID
        LEFT JOIN colors C ON C.colorID = q.colorID
        LEFT JOIN sizes S ON S.sizeID = q.sizeID
        --WHERE q.productID = @productID 

这是:

代码语言:javascript
运行
复制
SELECT p.productID, p.product, C.color, C.colorID, S.size, S.sizeID, q.qty From quantities q
        inner join products P ON p.productID = q.productID
        INNER JOIN colors C ON C.colorID = q.colorID
        INNER JOIN sizes S ON S.sizeID = q.sizeID
        --WHERE q.productID = @productID 
    UNION 
    SELECT p.productID, p.product, NULL, NULL, S.size, S.sizeID, q.qty From quantities q
        inner join products P ON p.productID = q.productID
        INNER JOIN sizes S ON S.sizeID = q.sizeID
    WHERE /* q.productID = @productID AND */ q.sizeID IS NOT NULL AND q.colorID IS NULL
    UNION
    SELECT p.productID, p.product, C.color, C.colorID, NULL, NULL, q.qty From quantities q
        inner join products P ON p.productID = q.productID
        INNER JOIN colors C ON C.colorID = q.colorID
    WHERE /* q.productID = @productID AND */ q.colorID IS NOT NULL AND q.sizeID IS NULL
    UNION
    SELECT p.productID, p.product, NULL, NULL, NULL, NULL, q.qty From quantities q
        inner join products P ON p.productID = q.productID
    WHERE /* q.productID = @productID AND */ q.colorID IS NULL AND q.sizeID IS NULL

编辑:

Server解析和编译时间: CPU时间= 32 ms,运行时间= 65 ms。(10排(S)受影响)表“尺寸”。扫描计数1,逻辑读取21,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.桌子的颜色。扫描计数1,逻辑读取21,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表“产品”。扫描计数0,逻辑读取20,物理读取1,先读0,lob逻辑读取0,lob物理读取0,lob预读读取0.表“数量”扫描计数1,逻辑读取2,物理读取1,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.Server执行时间: CPU时间=0 ms,运行时间= 12 ms。(10排(S)受影响)表“产品”。扫描计数0,逻辑读取20,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表“数量”扫描计数4,逻辑读取8,物理读取0,先读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.桌子‘工作表’扫描计数0,逻辑读取0,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.桌子的尺寸。扫描计数0,逻辑读取18,物理读取0,先读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.桌子的颜色。扫描计数0,逻辑读取12,物理读取0,先读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.Server执行时间: CPU时间=0 ms,运行时间=0 ms。

在我看来,这是对性能最好的第二个查询,更大的联合查询。

你们中有人知道为什么会发生这样的事情吗?还是我必须提供更多的信息(表格信息之类的东西)?

执行计划:

谢谢!

EN

回答 4

Database Administration用户

回答已采纳

发布于 2013-11-02 14:37:10

有时,我想知道短脚本是否真的是最好的关注对象。

脚本的大小与查询的执行效率无关。更紧凑的语句在编译方面可能会消耗更少的资源,但是(重新)编译在活动系统中通常是罕见的。

但是,更少的表访问通常是可取的,这确实会导致更紧凑的代码。

一般说来,较小的执行计划会产生更好的结果,而较低的估计成本则会产生更好的结果。尽管如此,这也是一种高度的情境化。在某些情况下,特别是费用估计数可能相差甚远。测量实际执行时间很重要,因为在一天结束时,这才是最重要的。

使用左联接,我只需几行就可以实现我想要的结果。但后来我尝试了一个更长的脚本,使用工会。哪一种是最好的方法?

首先,我们需要知道在真正的系统中这些表中有多少数据。现在,很少有人使用STATISTICS TIME性能指标来确定赢家--返回的结果将由查询执行以外的其他因素主导。有了更多的数据,计划很可能会改变,因此这里的比较毫无意义。

话虽如此,从逻辑的角度来看查询计划,第一个是赢家。

您可以看到,quantities的聚集索引扫描在第一个计划中显示一次,而在第二个计划中显示四次。第二个计划还包含了使用UNIONs的另一种昂贵的不同类型(这个操作符可以通过使用UNION ALLs来消除,这不会改变结果)。

第一个查询也可能得到改进,方法是在colorssizes表上获取索引查找,而不是进行表扫描。尝试哈希匹配计划也是值得的(当quantitiesproducts更大时,您可能会看到这一点),但是对于这么小的表,启动成本可能会太高而没有好处。

我建议您运行每个要在循环中测试10,000+时间的语句,计算出平均执行时间,然后进行比较。

票数 5
EN

Database Administration用户

发布于 2013-11-01 16:58:00

没有了整个数据库,这是一个很难回答的问题。我能说的是:你可以测试你自己。

如果您使用“设置统计时间”,或者使用

代码语言:javascript
运行
复制
DECLARE @StartTime DATETIME = GETDATE()

/Some Query Here/

SELECT 'Total Run Time Query 1: ' + CAST(DATEDIFF(MS,@StartTime,GETDATE())

SET @StartTime = GETDATE()

/Some Other Query Here/

SELECT 'Total Run Time Query 2: ' + CAST(DATEDIFF(MS,@StartTime,GETDATE())

您可以获得查询执行时间。

对于I/O,可以使用SET STATISTICS IO并运行查询。

另一种方法是启动分析器并捕获查询跟踪,这也会给出详细信息。

使用这些方法,您可以测试需要测试的任何东西,并且是我在调优查询时使用的方法。一旦得到结果,您就可以根据什么是重要的、总体运行时间、磁盘IO或cpu时间来决定哪个更快。在不同的系统中,我发现更快并不总是意味着时间。

票数 1
EN

Database Administration用户

发布于 2013-11-02 10:47:47

您不应该在第二个查询中使用UNION ALL而不是UNION吗?

结果集看起来是不同的。它可能会从第二个计划中删除一个或多个操作(可能是排序)。

关于这个问题:对于我来说,最基本的规则就是尽可能少地处理你所要处理的数据集。我倾向于避免外部加入这只是开始编写查询时的第一条经验规则,显然存在大量异常。。

我也同意..。您使用的测试数据太小了。

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/52668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档