TSQL加入,查询处理顺序和存储

时间:2016-05-14 17:02:51

标签: sql-server tsql join query-optimization

表格结构:

CREATE TABLE dbo.Transactions
(
    actid INT NOT NULL, --Account ID
    tranid INT NOT NULL,  -- Transaction ID
    val MONEY NOT NULL, --- Transaction value

    CONSTRAINT PK_Transactions PRIMARY KEY(actid, tranid)
);

以下低效查询尝试确定每次事务后的运行余额

SELECT 
    T1.actid, T1.tranid, T1.val,
    SUM(T2.val) AS balance
FROM 
    dbo.Transactions AS T1
JOIN 
    dbo.Transactions AS T2 ON T2.actid = T1.actid
                           AND T2.tranid <= T1.tranid
GROUP BY 
    T1.actid, T1.tranid, T1.val;

我不确定如何在查询中处理联接。是否将连接视为子查询,其中每个组(T1.actid, T1.tranid, T1.val)执行连接语句?这是否意味着如果有10K交易,则此查询会创建10K个加入的数据集?

3 个答案:

答案 0 :(得分:0)

在SSMS中执行查询。然后突出显示它并按 Ctrl + L 查看执行计划。这将向您展示SQL Server如何计划执行查询,有时还会建议索引等。

答案 1 :(得分:0)

这意味着您将拥有连接满足的确切行数

处理T1中的每一行并从T2中引入满足连接条件的行。

连接可以作为循环,散列或合并进行处理。通常,优化器使用哈希。

最好的想法就是运行它。输出应该讲述一个故事。

答案 2 :(得分:0)

了解的唯一方法是通过学习&#39;查询计划。

仅供参考:在我看来,您的查询等同于

SELECT 
    T1.actid, T1.tranid, T1.val,
    balance = (SELECT SUM(T2.val)
                 FROM dbo.Transactions
                WHERE T2.actid = T1.actid
                  AND T2.tranid <= T1.tranid)
FROM 
    dbo.Transactions AS T1

说实话,我更喜欢这个&#39;版本,因为它看起来更具可读性;我还希望这个版本能够稍微“瘦”一点。因为不需要排序,但只有实际的测试才能说明。看到优化器在幕后做了什么,有时会令人惊讶!同样,查询计划将显示。

因此,运行两个查询并比较生成的查询计划,这些应该可以让您了解它们的相对成本。现在,请记住&#34;成本&#34;并不总是与&#34; time&#34 ;;因此,您可能希望检查哪一个在您的硬件上以及在典型负载下运行得更快;还要记住,例如缓存可能会产生影响!