TSQL Join、查询处理顺序和存储
Posted
技术标签:
【中文标题】TSQL Join、查询处理顺序和存储【英文标题】:TSQL Join, Query Processing order and storage 【发布时间】:2016-05-14 17:02:51 【问题描述】:表结构:
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 Transactions ,则此查询会创建 10K 连接数据集?
【问题讨论】:
【参考方案1】:在 SSMS 中执行您的查询。然后突出显示它并按 Ctrl + L 以查看执行计划。这将向您展示 SQL Server 计划如何执行查询,有时还会建议索引等。
【讨论】:
【参考方案2】:这意味着您将拥有连接满足的确切行数
处理 T1 中的每一行,并从 T2 中引入满足连接条件的行。
连接可以被处理为循环、散列或合并。通常优化器不使用哈希。
最好的办法就是运行它。输出应该讲述一个故事。
【讨论】:
【参考方案3】:了解的唯一方法是“研究”查询计划。
仅供参考:在我看来,您的查询相当于
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
说实话,我更喜欢“这个”版本,因为它对我来说更具可读性;我还希望这个版本稍微“精简”,因为对排序的需求较少,但只有实际测试才能说明问题。有时看到优化器在幕后做了什么令人惊讶!再次显示查询计划。
因此,运行两个查询并比较生成的查询计划,这些应该让您了解它们的相对成本。现在,请记住,“成本”并不总是与“时间”直接相关。所以你可能想检查哪一个在你的硬件上和“典型负载”下运行得更快;还要记住,例如缓存可能会在这里产生影响!
【讨论】:
以上是关于TSQL Join、查询处理顺序和存储的主要内容,如果未能解决你的问题,请参考以下文章
数据库工程开发秘籍之TSQL 存储过程user stored procedure的概念与案例实战