标签: computed-column

有没有办法防止计算列中的标量 UDF 抑制并行性?

已经有很多关于SQL Server中标量 UDF危险的文章。随意搜索将返回大量结果。

不过,有些地方标量 UDF 是唯一的选择。

例如:处理 XML 时:XQuery 不能用作计算列定义。Microsoft 记录的一种选择是使用标量 UDF将 XQuery 封装在标量 UDF 中,然后在计算列中使用它。

这会产生各种影响和一些解决方法。

  • 查询表时逐行执行
  • 强制对表的所有查询串行运行

您可以通过对函数进行架构绑定来绕过逐行执行,并保留计算列或对其进行索引。即使未引用标量 UDF,这两种方法都不能阻止强制序列化查询表。

有没有一种已知的方法可以做到这一点?

sql-server parallelism functions computed-column

31
推荐指数
2
解决办法
2699
查看次数

SQL Server 是否只在 SELECT 列表中执行一次计算?

以下面的例子为例:

SELECT <CalculationA> As ColA,
       <CalculationB> As ColB,
       <CalculationA> + <CalculationB> As ColC
FROM TableA
Run Code Online (Sandbox Code Playgroud)

CalculationA 和CalculationB 会分别计算两次吗?
或者优化器是否足够聪明来计算一次并使用结果两次?

我想进行测试以查看自己的结果,但是,我不确定如何检查这样的事情。

我的假设是它会执行两次计算。
在哪种情况下,根据所涉及的计算,使用派生表或嵌套视图会更好吗?考虑以下:

SELECT TableB.ColA,
       TableB.ColB,
       TableB.ColA + TableB.ColB AS ColC,
FROM(    
      SELECT <CalculationA> As ColA,
             <CalculationB> As ColB
      FROM TableA
    ) As TableB
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望计算只执行一次?

请问有人可以证实或反驳我的假设吗?或者指导我如何为自己测试这样的东西?

谢谢。

sql-server view computed-column

30
推荐指数
2
解决办法
3565
查看次数

什么时候计算计算列?

计算列的值何时确定?

  • 何时取回值?
  • 值什么时候改变?
  • 其他时间?

我猜这是一个新手问题,因为我在搜索中没有找到任何东西。

sql-server computed-column

29
推荐指数
2
解决办法
7962
查看次数

持久计算列上的索引需要键查找以获取计算表达式中的列

我在一个表上有一个持久计算列,它只是由连接列组成,例如

CREATE TABLE dbo.T 
(   
    ID INT IDENTITY(1, 1) NOT NULL CONSTRAINT PK_T_ID PRIMARY KEY,
    A VARCHAR(20) NOT NULL,
    B VARCHAR(20) NOT NULL,
    C VARCHAR(20) NOT NULL,
    D DATE NULL,
    E VARCHAR(20) NULL,
    Comp AS A + '-' + B + '-' + C PERSISTED NOT NULL 
);
Run Code Online (Sandbox Code Playgroud)

Comp不是唯一的,并且 D 是每个组合的有效起始日期A, B, C,因此我使用以下查询来获取每个组合的结束日期A, B, C(基本上是 Comp 相同值的下一个开始日期):

SELECT  t1.ID,
        t1.Comp,
        t1.D,
        D2 = (  SELECT  TOP 1 t2.D
                FROM    dbo.T t2
                WHERE   t2.Comp = …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server execution-plan computed-column bookmark-lookup

24
推荐指数
2
解决办法
3228
查看次数

无法在计算列上创建筛选索引

在我之前的一个问题中,在向表中添加新的计算列时禁用锁升级是个好主意吗?,我正在创建一个计算列:

ALTER TABLE dbo.tblBGiftVoucherItem
ADD isUsGift AS CAST
(
    ISNULL(
        CASE WHEN sintMarketID = 2 
            AND strType = 'CARD'
            AND strTier1 LIKE 'GG%' 
        THEN 1 
        ELSE 0 
        END
    , 0) 
    AS BIT
) PERSISTED;
Run Code Online (Sandbox Code Playgroud)

计算列是PERSISTED,并且根据计算列定义(Transact-SQL)

坚持

指定数据库引擎将计算值物理存储在表中,并在计算列所依赖的任何其他列更新时更新值。将计算列标记为 PERSISTED 允许在确定性但不精确的计算列上创建索引。有关更多信息,请参阅计算列上的索引。任何用作分区表的分区列的计算列都必须显式标记为 PERSISTED。当指定 PERSISTED 时,computed_column_expression 必须是确定性的。

但是当我尝试在我的列上创建索引时,我收到以下错误:

CREATE INDEX FIX_tblBGiftVoucherItem_incl
ON dbo.tblBGiftVoucherItem (strItemNo) 
INCLUDE (strTier3)
WHERE isUsGift = 1;
Run Code Online (Sandbox Code Playgroud)

无法在表 'dbo.tblBGiftVoucherItem' 上创建过滤索引 'FIX_tblBGiftVoucherItem_incl',因为过滤器表达式中的列 'isUsGift' 是计算列。重写过滤器表达式,使其不包含此列。

如何在计算列上创建过滤索引?

或者

有替代的解决方案吗?

index sql-server filtered-index sql-server-2014 computed-column

19
推荐指数
3
解决办法
4271
查看次数

PostgreSQL:生成的列

PostgreSQL 是否支持生成的列?也称为虚拟列。我不是在谈论IDENTITY

我找不到有关此卓越功能的任何信息,但我知道它在 SQL Server 以及最新版本的 MariaDB 和 MySQL 中可用。

SQL:2003标准中提到了该功能,并且在 2006 年左右在 PostgreSQL 论坛上进行了一些讨论,但我找不到关于此事的任何实质性内容。

有一些关于 SO 的讨论,但它现在已经很老了,所以它很可能已经过时了。

postgresql computed-column

19
推荐指数
3
解决办法
1万
查看次数

为什么 NOT NULL 计算列在视图中被认为可以为空?

我有一张桌子:

CREATE TABLE [dbo].[Realty](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [RankingBonus] [int] NOT NULL,
    [Ranking]  AS ([Id]+[RankingBonus]) PERSISTED NOT NULL
    ....
)
Run Code Online (Sandbox Code Playgroud)

还有一个观点:

CREATE View  [dbo].[FilteredRealty] AS
 SELECT 
realty.Id as realtyId,
...
COALESCE(realty.Wgs84X, ruian_cobce.Wgs84X, ruian_obec.Wgs84X) as Wgs84X,
COALESCE(realty.Wgs84Y, ruian_cobce.Wgs84Y, ruian_obec.Wgs84Y) as Wgs84Y,
realty.Ranking,
...
FROM realty
JOIN Category ON realty.CategoryId = Category.Id
LEFT JOIN ruian_cobce ON realty.cobceId = ruian_cobce.cobce_kod
LEFT JOIN ruian_obec ON realty.obecId = ruian_obec.obec_kod
LEFT JOIN okres ON realty.okresId = okres.okres_kod
LEFT JOIN ExternFile ON realty.Id = ExternFile.ForeignId AND …
Run Code Online (Sandbox Code Playgroud)

null sql-server view computed-column

17
推荐指数
2
解决办法
8741
查看次数

SQL Server 使用与定义不匹配的数据填充 PERSISTED 列是否合法?

我正在跟进有关计算列中奇怪值的问题PERSISTED。那里的答案对这种行为是如何产生的做出了一些猜测。

我在问以下问题:这不是一个彻头彻尾的错误吗?被PERSISTED列曾经允许这样的行为?

DECLARE @test TABLE (
    Col1 INT,
    Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED) --depends on Col1

INSERT INTO @test (Col1) VALUES
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5)),
    (ABS(CHECKSUM(NEWID()) % 5))

SELECT * FROM @test --shows impossible data

UPDATE @test SET Col1 = Col1*1 --"fix" the data by rewriting it

SELECT * FROM @test --observe fixed data

/*
Col1    Contains2
2   0 …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2014 computed-column

16
推荐指数
1
解决办法
520
查看次数

不可查找的持久计算列上的索引

我有Address一个名为 的表,它有一个名为 的持久计算列Hashkey。该列是确定性的,但不精确。它有一个不可查找的唯一索引。如果我运行这个查询,返回主键:

SELECT @ADDRESSID= ISNULL(AddressId,0)
FROM dbo.[Address]
WHERE HashKey = @HashKey
Run Code Online (Sandbox Code Playgroud)

我得到这个计划:

基本计划

如果我强制索引,我会得到更糟糕的计划:

力指数

如果我尝试同时强制索引和查找,则会出现错误:

由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用的情况下重新提交查询SET FORCEPLAN

这仅仅是因为它不精确吗?我以为坚持就无所谓了?

有没有办法在不使其成为非计算列的情况下使该索引可查找?

有没有人有任何有关此信息的链接?

我无法发布实际的表创建,但这里有一个具有相同问题的测试表:

drop TABLE [dbo].[Test]

CREATE TABLE [dbo].[Test]
  (
     [test]        [VARCHAR](100) NULL,
     [TestGeocode] [geography] NULL,
     [Hashkey] AS CAST(
                        ( hashbytes
                            ('SHA', 
                                ( RIGHT(REPLICATE(' ', (100)) + isnull([test], ''), ( 100 )) ) 
                                + RIGHT(REPLICATE(' ', (100)) + isnull([TestGeocode].[ToString](), ''), ( 100 ))
                            ) 
                        ) AS BINARY(20)                                                                                                        
                      ) PERSISTED
    CONSTRAINT [UK_Test_HashKey] UNIQUE NONCLUSTERED([Hashkey])
  )    
GO    
DECLARE @Hashkey …
Run Code Online (Sandbox Code Playgroud)

index sql-server optimization sql-server-2012 computed-column

15
推荐指数
2
解决办法
532
查看次数

未使用计算列索引

我想根据两列是否相等进行快速查找。我尝试使用带有索引的计算列,但 SQL Server 似乎没有使用它。如果我只使用带有索引的静态填充位列,我会得到预期的索引查找。

似乎还有其他一些类似的问题,但没有一个关注为什么不使用索引。

测试表:

CREATE TABLE dbo.Diffs
    (
    Id int NOT NULL IDENTITY (1, 1),
    DataA int NULL,
    DataB int NULL,
    DiffPersisted  AS isnull(convert(bit, case when [DataA] is null and [DataB] is not null then 1 when [DataA] <> [DataB] then 1 else 0 end), 0) PERSISTED ,
    DiffComp  AS isnull(convert(bit, case when [DataA] is null and [DataB] is not null then 1 when [DataA] <> [DataB] then 1 else 0 end), 0),
    DiffStatic bit not null,
    Primary …
Run Code Online (Sandbox Code Playgroud)

sql-server index-tuning computed-column

14
推荐指数
2
解决办法
1085
查看次数