我正在努力寻找有关 SQL Server 如何实际存储非持久计算列的任何文档。
以下面的例子为例:
--SCHEMA
CREATE TABLE dbo.Invoice
(
InvoiceID INT IDENTITY(1, 1) PRIMARY KEY,
CustomerID INT FOREIGN KEY REFERENCES dbo.Customer(CustomerID),
InvoiceStatus NVARCHAR(50) NOT NULL,
InvoiceStatusID AS CASE InvoiceStatus
WHEN 'Sent' THEN 1
WHEN 'Complete' THEN 2
WHEN 'Received' THEN 3
END
)
GO
--INDEX
CREATE NONCLUSTERED INDEX IX_Invoice ON Invoice
(
CustomerID ASC
)
INCLUDE
(
InvoiceStatusID
)
GO
Run Code Online (Sandbox Code Playgroud)
我知道它存储在叶级别,但是如果该值没有持久化,那么如何存储任何内容?在这种情况下,索引如何帮助 SQL Server 找到这些行?
非常感谢任何帮助,
非常感谢,
编辑:
感谢 Brent & Aaron 回答这个问题,这里的 PasteThePlan清楚地展示了他们的解释。
使用下面的示例,谓词是相同的,但是顶部语句(正确)返回 0 行,底部语句返回 1 - 即使谓词不匹配:
declare @barcode nchar(22)=N'RECB012ZUKI449M1VBJZ'
declare @tableId int = null
declare @total decimal(10, 2) = 5.17
SELECT 1
FROM
[dbo].[transaction] WITH (INDEX([IX_Transaction_TransactionID_PaymentStatus_DeviceID_DateTime_All]))
WHERE
Barcode = @barcode
AND StatusID = 1
AND TableID = @tableID
AND @total <= Total
SELECT 1
FROM
[dbo].[transaction]
WHERE
Barcode = @barcode
AND StatusID = 1
AND TableID = @tableID
AND @total <= Total
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?
更多信息:
Microsoft SQL Azure (RTM) - 12.0.2000.8 Dec 19 2018 …
我刚刚经历了一些旧的存储过程,做了一些优化,偶然发现了这个奇怪的地方:
SELECT ISNULL(bt.BusinessTypeID, 0) AS BusinessTypeID
FROM BusinessType bt
LEFT JOIN Business b
ON b.BusinessTypeID = ISNULL(bt.BusinessTypeID, NULL)
Run Code Online (Sandbox Code Playgroud)
这是一个稍微简化的版本,但第 4 行是有问题的行。我无法想象这有什么作用?我已经检查了带有和不带有此 NULL 检查的 exec 计划和结果,一切似乎都一样。
这只是完全的疯狂还是有一些模糊的原因为什么离开它可能是有益的?
更新:
为了回应评论,在下面添加了完整的查询(匿名),在这个完整版本中,这ON Object4.Column9 = Function4(Object1.Column4, ?)
对应于这个ON b.BusinessTypeID = ISNULL(bt.BusinessTypeID, NULL)
。另外 Object4.Column9 是一个可以为空的外键 & Object1.Column4 是一个不可为空的主键
SELECT Function1() AS Column1,
Function2(Function3(Function2((
SELECT Column2 AS Column3
FROM
(
SELECT ? AS Column4,
? AS Column2
WHERE (Variable1 IS NULL OR ? = Variable1)
UNION ALL
SELECT Function4(Object1.Column4, ?) AS Column4,
Function4(Object1.Column5,?) + …
Run Code Online (Sandbox Code Playgroud) 我做的长时间运行的存储过程的一些分析和所遇到的异常的东西,根据网上图书sys.dm_exec_procedure_stats
应该只显示一个每缓存的存储过程的计划行,但是有存储过程一个用户出现两次在表中。
此存储过程的两个“版本”具有截然不同的执行时间/计数。
这仅仅是因为缓存和使用了不同的计划吗?如果是这样,我没有意识到 sql server 为同一个 object_id 缓存了多个计划,我认为这是一种一对一的交易?另外,如果是这种情况,它似乎与 DMV 的 BOLS 定义相矛盾?
继此,如果是使用计划的两个版本,我怎么能知道在什么情况下使用什么样的计划?
其他人遇到过这个吗?