行版本控制为每行维护 14 个字节的内部版本控制信息。但这真的是每行的成本,还是也适用于表上每个索引的成本?
似乎这 14 个字节也必须添加到所有索引记录中,以便仅索引扫描(和其他仅索引访问)可以看到版本控制信息并感知数据的时间点快照。
不过,我在网上可以找到的所有信息都只讨论了每行 14 字节的开销。
行版本控制为每行维护 14 个字节的内部版本控制信息。但这真的是每行的成本,还是也适用于表上每个索引的成本?
似乎这 14 个字节也必须添加到所有索引记录中,以便仅索引扫描(和其他仅索引访问)可以看到版本控制信息并感知数据的时间点快照。
不过,我在网上可以找到的所有信息都只讨论了每行 14 字节的开销。
观察使用 Live Query Statistics 执行的查询,我注意到SQL Server似乎正在从散列连接的构建输入中懒惰地构建散列表。
在 0 个探测行的情况下,这是一个有意义的差异。它可能会保存整个构建端树。
我一直认为哈希是这样运行的:
但它是下面的吗?
我不确定如何最终测试它是哪种方式。我不确定以这种方式可以信任实时查询统计输出。有谁知道这是如何工作的?
我在一个巨大的REORGANIZE
. 为了加快速度,我设置了DELAYED_DURABILITY = FORCED
.
这会影响运行语句吗?我查看了服务器上的 IO 和 CPU 编号,但看不出有什么不同。我也不确定是否会有任何差异,所以我无法判断。
我的表如下所示:
GroupID INT NOT NULL
SomeValue INT NOT NULL
我想GroupID
在结果集中保持相同的行。不过,这些组本身应该随机排序。SomeValue
应该是次要的排序标准。像这样:
GroupID, SomeValue
13, 1
13, 2
7, 1
7, 2
11, 1
11, 2
...
ORDER BY GroupID, SomeValue
不会随机排列组。ORDERBY NEWID()
是完全随机的。ORDER BY SomeHash(GroupID), SomeValue
我想到了,但我每次都需要一个新的随机订单。
如何才能做到这一点?
当你a + b
在 T-SQL 中说 anda
和b
are of a string type (eg varchar(...)
or nvarchar(...)
) 时:结果类型是如何确定的?
我在试验时没有发现明确的规则。这似乎取决于是否涉及文字。
另外,长度是怎么确定的?我发现的类型'x' + 'y'
是varchar(2)
. 显然,正在跟踪文字的长度。
这是我进行的一个小实验:
USE tempdb
DECLARE @v VARCHAR(400) = 'x'
DECLARE @n NVARCHAR(400) = 'x'
SELECT
'' AS [varchar]
, N'' AS [nvarchar]
, ('x' + N'x') AS ['x' + N'x']
, (N'x' + 'x') AS [N'x' + 'x']
, (ISNULL('x', N'x')) AS [ISNULL('x', N'x')]
, (ISNULL(N'x', 'x')) AS [ISNULL(N'x', 'x')]
, (COALESCE('x', N'x')) AS [COALESCE('x', N'x')]
, (COALESCE(N'x', 'x')) AS [COALESCE(N'x', 'x')]
, (@v + @n) AS [@v + @n]
, (@n + @v) AS [@n + @v]
, (ISNULL(@v, @n)) AS [ISNULL(@v, @n)]
, (ISNULL(@n, @v)) AS [ISNULL(@n, @v)]
, (COALESCE(@v, @n)) AS [COALESCE(@v, @n)]
, (COALESCE(@n, @v)) AS [COALESCE(@n, @v)]
INTO StringConversionTest
文档指出了 的行为,ISNULL
所以COALESCE
我理解那部分。但+
运营商似乎在一套更复杂的规则下行事。
为了节省许可成本,我正在评估是否可以使用 VLDB 的标准版。我将概述场景:
我想知道我需要企业版做什么。我不会从分区中获得任何好处,因为我不想切换分区或将它们放在不同的存储上。数据压缩可以为我们节省 50%,但我们使用的是廉价存储。与昂贵的许可证相比,节省的费用微不足道。
对于 HA,我不明白为什么我不能使用已弃用但仍在工作的镜像。这并不理想,但企业版为不明确的收益付出了高昂的代价。
尽管如此,在这里使用标准版还是让我感到紧张,因为它不是通常推荐的版本,而且似乎隐约存在风险。在这种情况下寻求一些建议。谢谢!
我正在使用执行以下形式查询的 ORM:
SELECT Columns
FROM T
WHERE Col LIKE @p0 ESCAPE '~'
Col
被索引并且索引被覆盖。谓词是非常有选择性的。这些表有 500,000 行。
我总是在查询字符串前缀(例如'prefix%'
)。显然,这不是 SQL Server 静态已知的。但我知道 SQL Server 基本上能够根据LIKE
带有前缀的模式进行查找。
我希望 SQL Server 在执行时发现要扫描的索引的相关范围,并且只扫描该范围。不过,我得到的执行计划有一个索引扫描。
ORM 不支持OPTION (RECOMPILE)
,我不确定它是否是一个好的选择,因为查询在大约 20 毫秒内执行。(但是我希望这个查询运行得更快。通过搜索,它应该能够在 ~1ms 内运行)。
我能以某种方式让 SQL Server 在这里执行查找吗?
我有以下形式的查询:
SELECT ...
FROM ColumnstoreTable cs
CROSS APPLY (
SELECT *
FROM (VALUES
('A', cs.DataA)
, ('B', cs.DataB)
, ('C', cs.DataC)
) x(Col0, Col1)
) someValues
这从 Columnstore 支持的子查询 ( ColumnstoreTable
) 中获取每一行并将这些行相乘。这本质上是一个UNPIVOT
. 真正的查询比这更大。查询的这一部分提供给其他处理。
这里的问题是这CROSS APPLY
是作为一个合理的选择的循环连接实现的。不幸的是,循环连接不支持批处理模式。
这部分查询对性能非常关键,我怀疑以批处理模式运行它可能对性能非常有益。
我怎样才能重写这个查询,这样我就不会退出批处理模式?
我确实尝试使用临时表而不是VALUES
,但这并没有改变没有相等连接条件来进行散列连接的事实。
正常JOIN ... ON ...
语法是众所周知的。但也可以将子句与其对应的ON
子句分开放置。JOIN
这在实践中很少见,在教程中找不到,我还没有找到任何网络资源,甚至提到这是可能的。
这是一个可以玩的脚本:
SELECT *
INTO #widgets1
FROM (VALUES (1), (2), (3)) x(WidgetID)
SELECT *
INTO #widgets2
FROM (VALUES (1, 'SomeValue1'), (2, 'SomeValue2'), (3, 'SomeValue3')) x(WidgetID, SomeValue)
SELECT *
INTO #widgetProperties
FROM (VALUES
(1, 'a'), (1, 'b'),
(2, 'a'), (2, 'b'))
x(WidgetID, PropertyName)
--q1
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN #widgets2 w2 ON w2.WidgetID = w1.WidgetID
LEFT JOIN #widgetProperties wp ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b'
ORDER BY w1.WidgetID
--q2
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN #widgets2 w2 --no ON clause here
JOIN #widgetProperties wp
ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b'
ON w2.WidgetID = w1.WidgetID
ORDER BY w1.WidgetID
--q3
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN (
#widgets2 w2 --no SELECT or FROM here
JOIN #widgetProperties wp
ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b')
ON w2.WidgetID = w1.WidgetID
ORDER BY w1.WidgetID
q1 看起来很正常。q2 和 q3 有这些不寻常的ON
从句定位。
这个脚本不一定有多大意义。我很难设计出一个有意义的场景。
那么这些不寻常的语法模式是什么意思呢?这是如何定义的?我注意到并非这两个ON
子句的所有位置和顺序都是允许的。管理这个的规则是什么?
编写这样的查询也是一个好主意吗?
我有一个报告损坏的空间索引:DBCC CHECKDB
DBCC CHECKDB(MyDB)
WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS, TABLERESULTS
空间索引、XML 索引或索引视图“sys.extended_index_xxx_384000”(对象 ID xxx)不包含视图定义生成的所有行。这不一定表示此数据库中的数据存在完整性问题。
空间索引、XML 索引或索引视图“sys.extended_index_xxx_384000”(对象 ID xxx)包含视图定义未生成的行。这不一定表示此数据库中的数据存在完整性问题。
CHECKDB 在表“sys.extended_index_xxx_384000”(对象 ID xxx)中发现 0 个分配错误和 2 个一致性错误。
修复等级为repair_rebuild
。
删除并重新创建索引不会删除这些损坏报告。不EXTENDED_LOGICAL_CHECKS
带但带DATA_PURITY
不报错。
此外,CHECKTABLE
此表需要 45 分钟,尽管其 CI 大小为 30 MB,并且有大约 30k 行。该表中的所有数据都是点geography
数据。
这种行为在任何情况下都是预期的吗?它说“这不一定代表完整性问题”。我应该做些什么?CHECKDB
正在失败,这是一个问题。
此脚本重现了该问题:
CREATE TABLE dbo.Cities(
ID int NOT NULL,
Position geography NULL,
CONSTRAINT PK_Cities PRIMARY KEY CLUSTERED
(
ID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
INSERT dbo.Cities (ID, Position) VALUES (20171, 0xE6100000010C4E2B85402E424A40A07312A518C72A40)
GO
CREATE SPATIAL INDEX IX_Cities_Position ON dbo.Cities
(
Position
)USING GEOGRAPHY_AUTO_GRID
WITH (
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
这是版本 12.0.4427.24 (SQL Server 2014 SP1 CU3)。
我用模式和数据、新数据库、执行编写了表。同样的错误。CHECKDB 也有令人难以置信的 45 分钟运行时间。我使用 SQL Profiler 捕获了 CHECKDB 查询计划。它有一个误入歧途的循环连接,显然会导致运行时间过长。该计划在表的行数中具有二次运行时间!双重嵌套扫描循环连接。
清除所有非空间索引不会改变任何东西。
运行报告CHECKDB
腐败在sys.extended_index_1066482673_384000
. 名称模式代表什么样的索引sys.extended_index_...
?消息是:
空间索引、XML 索引或索引视图“sys.extended_index_1066482673_384000”(对象 ID ...)不包含视图定义生成的所有行。这不一定表示此数据库中的数据存在完整性问题。有关对空间索引、XML 索引和索引视图的 DBCC 错误进行故障排除的详细信息,请参阅 SQL Server 联机丛书。
数据库快照文件是稀疏文件。只有当页面被修改时,才会写入稀疏文件。读取快照必须能够知道稀疏文件是否包含复制页面。SQL Server 如何知道从哪里读取?这些信息存储在哪里?
在我的开发盒上,我的 SQL Server 配置了最大内存量(8GB 或 16GB)。这是许多开发任务所必需的。
不过,有时我想找回我的记忆。我不想让 8GB 永久消耗。
什么是让 SQL Server 突然将其所有内存释放给操作系统的好方法?
DBCC DROPCLEANBUFFERS
不这样做。它只是将干净的缓冲区标记为可用。
重新启动 SQL Server 是一个问题,因为由于此错误/功能,这会导致运行 1 分钟的数据库恢复:停止 SQL Server 服务会导致数据库无法完全关闭(请为该连接项投票;似乎是一个严重的错误) .