【发布时间】:2023-03-19 19:36:02
【问题描述】:
经常遇到这样的情况,需要将一个大表加入到某个表的某个变换中。
我做了一个大表和小价格表的例子。
输入表格 CarPrices,其中包含每个汽车品牌/型号的价格以及开始和结束日期。我想将所有售出的汽车加入 CarPrices 表中的销售价格,在 PriceStartingDate 和 PriceEndingDate 之间的条件 SaleDate 上,但如果该期间没有价格,我想加入找到的最新价格。
我可以这样完成,但速度非常慢:
WITH CarPricesTransformation AS (
SELECT CarBrand, CarModel, PriceStartingDate,
CASE WHEN row_number() OVER (PARTITION BY CarBrand, CarModel,
ORDER BY PriceStartingDate DESC) = 1
THEN NULL ELSE PriceEndingDate END PriceEndingDate,
Price
FROM CarPrices
)
SELECT SUM(Price)
FROM LargeCarDataBase C
INNER JOIN CarPricesTransformation P
ON C.CarBrand = P.CarBrand
AND C.CarModel = P.CarModel
AND C.SaleDate >= P.PriceStartingDate
AND (C.SaleDate <= P.PriceEndingDate OR P.PriceEndingDate IS NULL)
一种更快的可靠方法是忘记创建 VIEW 并改为创建存储过程,我首先将较小的价格表准备为具有正确聚集索引的临时表,然后对其进行连接。这要快得多。但我想坚持一个观点。
有什么想法吗...?
【问题讨论】:
-
请参阅Quassnoi's answer here 如果您希望中间结果具体化和索引,最好使用
#temp表显式执行此操作,尽管答案中的链接提供了使用计划执行此操作的示例指导。 -
我很困惑,您使用的视图名称是什么?看起来您可能正在交替使用 CTE/View。这是一个你应该改掉的习惯,因为它们不是一回事。
-
你的执行计划是怎么说的?这可以通过添加/修改表上的索引来解决...
-
@Abe。我认为问题中的代码是视图定义。
CREATE VIEW foo AS <op's code goes here> -
您有一些指标可以使用吗? LargeCarDataBase 中的记录数? CarPricesTransformation 中的记录数?每辆车的平均价格等?
标签: sql sql-server-2008 tsql common-table-expression indexed-views