我正在开发一个 SQL Server 2012 数据库,我有一个关于一对零或一关系的问题。
我有两张桌子,Codes
和HelperCodes
。一个代码可以有零个或一个辅助代码。这是创建这两个表及其关系的 sql 脚本:
CREATE TABLE [dbo].[Code]
(
[Id] NVARCHAR(20) NOT NULL,
[Level] TINYINT NOT NULL,
[CommissioningFlag] TINYINT NOT NULL,
[SentToRanger] BIT NOT NULL DEFAULT 0,
[LastChange] NVARCHAR(50) NOT NULL,
[UserName] NVARCHAR(50) NOT NULL,
[Source] NVARCHAR(50) NOT NULL,
[Reason] NVARCHAR(200) NULL,
[HelperCodeId] NVARCHAR(20) NULL,
CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
(
[Id] ASC
),
CONSTRAINT [FK_Code_LevelConfiguration]
FOREIGN KEY ([Level])
REFERENCES [dbo].[LevelConfiguration] ([Level]),
CONSTRAINT [FK_Code_HelperCode]
FOREIGN KEY ([HelperCodeId])
REFERENCES [dbo].[HelperCode] ([HelperCodeId])
)
CREATE TABLE …
Run Code Online (Sandbox Code Playgroud) 我一直在一个表中记录昂贵的运行查询及其查询计划,以便我们监控性能趋势并确定需要优化的区域。
然而,现在已经到了查询计划占用太多空间的地步(因为我们针对每个查询存储整个计划)。
因此,我试图通过将 QueryPlanHash 和 QueryPlan 提取到另一个表来规范化现有数据。
CREATE TABLE QueryPlans
(
QueryPlanHash VARBINARY(25),
QueryPlan XML,
CONSTRAINT PK_QueryPlans PRIMARY KEY
(
QueryPlanHash
)
);
Run Code Online (Sandbox Code Playgroud)
由于query_plan_hash
in的定义sys.dm_exec_query_stats
是一个二进制字段(并且我会定期插入新数据),因此我使用VARBINARY
了新表中的数据类型。
但是,下面的插入失败了...
INSERT INTO QueryPlans
( QueryPlanHash, QueryPlan )
SELECT queryplanhash, queryplan
FROM
(
SELECT
p.value('(./@QueryPlanHash)[1]', 'varchar(20)') queryplanhash,
QueryPlan,
ROW_NUMBER() OVER (PARTITION BY p.value('(./@QueryPlanHash)[1]', 'varchar(20)') ORDER BY DateRecorded) rownum
FROM table
CROSS APPLY QueryPlan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple[@QueryPlanHash]') t(p)
) data
WHERE rownum = 1
Run Code Online (Sandbox Code Playgroud)
....有错误
Implicit conversion from data type varchar to varbinary is …
Run Code Online (Sandbox Code Playgroud) 检查 VARCHAR 字段是否具有非 Ascii 字符的最佳方法是什么?
CHAR(1)
通过CHAR(31)
和CHAR(127)
通过CHAR(255)
。
我尝试使用PATINDEX
并遇到了以下问题。
检查下范围是否正常工作。
SELECT *
FROM mbrnotes
WHERE PATINDEX('%[' + CHAR(1)+ '-' +CHAR(31)+']%',LINE_TEXT) > 0
Run Code Online (Sandbox Code Playgroud)
我的数据有 0x1E 的三个记录,并且所有三个都返回了。
但是当我只检查上限时:
SELECT *
FROM mbrnotes
WHERE PATINDEX('%[' + CHAR(127)+ '-' +CHAR(255)+']%',LINE_TEXT) > 0
Run Code Online (Sandbox Code Playgroud)
它返回接近表中的所有记录(表计数 170737 并返回计数 170735),并且由于我的数据在此范围内没有任何值,我认为它不应该返回任何记录。
我们在生产环境(SQL Server 2012 SP2 - 是的......我知道......)中看到了很多这些查询内并行线程死锁,但是当查看通过扩展事件捕获的死锁 XML 时,受害者列表是空的。
<victim-list />
Run Code Online (Sandbox Code Playgroud)
死锁似乎在 4 个线程之间,两个线程WaitType="e_waitPipeNewRow"
和两个WaitType="e_waitPipeGetRow"
.
<resource-list>
<exchangeEvent id="Pipe13904cb620" WaitType="e_waitPipeNewRow" nodeId="19">
<owner-list>
<owner id="process4649868" />
</owner-list>
<waiter-list>
<waiter id="process40eb498" />
</waiter-list>
</exchangeEvent>
<exchangeEvent id="Pipe30670d480" WaitType="e_waitPipeNewRow" nodeId="21">
<owner-list>
<owner id="process368ecf8" />
</owner-list>
<waiter-list>
<waiter id="process46a0cf8" />
</waiter-list>
</exchangeEvent>
<exchangeEvent id="Pipe13904cb4e0" WaitType="e_waitPipeGetRow" nodeId="19">
<owner-list>
<owner id="process40eb498" />
</owner-list>
<waiter-list>
<waiter id="process368ecf8" />
</waiter-list>
</exchangeEvent>
<exchangeEvent id="Pipe4a106e060" WaitType="e_waitPipeGetRow" nodeId="21">
<owner-list>
<owner id="process46a0cf8" />
</owner-list>
<waiter-list>
<waiter id="process4649868" />
</waiter-list>
</exchangeEvent> …
Run Code Online (Sandbox Code Playgroud) 我试图了解统计抽样是如何工作的,以及以下是否是抽样统计更新的预期行为。
我们有一个按日期分区的大表,有几十亿行。分区日期是先前的营业日期,因此是升序键。我们只将前一天的数据加载到该表中。
数据加载在夜间运行,因此在 4 月 8 日星期五,我们加载了 7 日的数据。
每次运行后,我们都会更新统计信息,尽管采取了一个样本,而不是一个FULLSCAN
.
也许我太天真了,但我希望 SQL Server 识别范围中的最高键和最低键,以确保它获得准确的范围样本。根据这篇文章:
对于第一个桶,下边界是生成直方图的列的最小值。
但是,它没有提到最后一个桶/最大值。
随着8日上午的抽样统计更新,该样本错过了表中的最高值(7日)。
由于我们对前一天的数据进行了大量查询,这会导致基数估计不准确和许多查询超时。
SQL Server 不应该识别该键的最高值并将其用作最大值RANGE_HI_KEY
吗?或者这只是不使用更新的限制之一FULLSCAN
?
版本 SQL Server 2012 SP2-CU7。我们目前无法升级,因为OPENQUERY
SP3中的行为改变了SQL Server 和 Oracle 之间的链接服务器查询中的数字四舍五入。
在 SQL Server 错误日志文件中,我发现了以下几行:
2018-02-22 14:10:58.95 spid17s Starting up database 'msdb'.
2018-02-22 14:10:58.95 spid16s Starting up database 'ReportServer'.
2018-02-22 14:10:58.95 spid18s Starting up database 'ReportServerTempDB'.
2018-02-22 14:10:58.95 spid19s Starting up database 'XYZ'.
Run Code Online (Sandbox Code Playgroud)
如果我在此之前检查数据库 XYZ 的状态,则ONLINE
使用以下语句:
SELECT state_desc FROM sys.databases WHERE name='XYZ'
Run Code Online (Sandbox Code Playgroud)
...但是当我尝试使用 C# 应用程序连接到该数据库时,它无法连接到该数据库。
错误是:
用户“asd”登录失败。
原因:无法打开明确指定的数据库。
我尝试了三个不同的用户(为应用程序定义的 Windows 用户、sa、SQL Server 用户)。当我在操作系统启动时运行应用程序时会出现问题,但是如果我在启动后手动启动它,则不会发生错误,因此我认为所有 SQL Server 设置和防火墙设置都是正确的。
在此之前,我还检查了服务状态是否正在运行。
我还应该检查什么以确保数据库实际上在线并准备好进行查询?
我正在寻找一个密钥,它告诉我可以查询数据库,而不是延迟一段时间(甚至不是基于明确的原因)。
我想扫描文本“启动数据库'XYZ'”的错误日志,但这意味着我必须为SQL Server错误日志的路径添加应用程序的设置。这也意味着多次阅读文件,直到我找到这句话。
因此,我们遇到了一个有趣的问题,即用户在尝试查询 SQL Server 2008 R2 中的视图时收到以下错误:
消息 7415,级别 16,状态 1,第 1 行 对 OLE DB 提供程序“Microsoft.ACE.OLEDB.12.0”的临时访问已被拒绝。您必须通过链接服务器访问此提供程序。
在研究这个问题时,我发现有很多文章列出了对 OPENROWSET 参数进行更改、注册表值更改、AdHoc 分布式查询等(链接到下面的文章)
http://www.johnsoer.com/blog/?p=538
按照上述链接中的步骤操作后,我们仍然收到错误消息。
这里需要注意的是,当我们创建一个测试帐户并给它 sa 时 - 它运行得很好。我的具有管理员访问权限的同事也可以毫无问题地运行查询。
此查询是从托管此实例的服务器本地的 excel 文件提供的。
任何人都知道 2008 年的任何其他修复程序?
我希望在 SQL Server 2008 数据库中填充日期维度表。表中的字段如下:
[DateId] INT IDENTITY(1,1) PRIMARY KEY
[DateTime] DATETIME
[Date] DATE
[DayOfWeek_Number] TINYINT
[DayOfWeek_Name] VARCHAR(9)
[DayOfWeek_ShortName] VARCHAR(3)
[Week_Number] TINYINT
[Fiscal_DayOfMonth] TINYINT
[Fiscal_Month_Number] TINYINT
[Fiscal_Month_Name] VARCHAR(12)
[Fiscal_Month_ShortName] VARCHAR(3)
[Fiscal_Quarter] TINYINT
[Fiscal_Year] INT
[Calendar_DayOfMonth] TINYINT
[Calendar_Month Number] TINYINT
[Calendar_Month_Name] VARCHAR(9)
[Calendar_Month_ShortName] VARCHAR(3)
[Calendar_Quarter] TINYINT
[Calendar_Year] INT
[IsLeapYear] BIT
[IsWeekDay] BIT
[IsWeekend] BIT
[IsWorkday] BIT
[IsHoliday] BIT
[HolidayName] VARCHAR(255)
Run Code Online (Sandbox Code Playgroud)
我编写了一个函数 DateListInRange(D1,D2),它返回两个参数日期 D1 和 D2 之间的所有日期。
IE。参数“2014-01-01”和“2014-01-03”将返回:
2014-01-01
2014-01-02
2014-01-03
Run Code Online (Sandbox Code Playgroud)
我想为一个范围内的所有日期填充 DATE_DIM 表,即 2010-01-01 到 2020-01-01。大多数字段都可以用 SQL 2008 DATEPART、DATENAME 和 YEAR …
sql-server-2008 data-warehouse business-intelligence dimension star-schema
我想编写一个脚本来列出我的数据库中的表以及该表中的列数。
像这样:
table name number
--------- --------
table1 1
table2 13
table3 2
table4 6
Run Code Online (Sandbox Code Playgroud) 我一直注意到我们的查询计划缓存存在一些我认为不寻常的问题,其中缓存中的计划从未超过一天。
通过运行以下查询(由Kimberly Tripp 提供),它表明大多数计划(4.5Gb 的 6Gb 缓存计划或 44813 的 ~50000)是使用计数为 1 的临时查询。
SELECT objtype AS [CacheType]
, count_big(*) AS [Total Plans]
, sum(cast(size_in_bytes as decimal(18,2)))/1024/1024 AS [Total MBs]
, avg(usecounts) AS [Avg Use Count]
, sum(cast((CASE WHEN usecounts = 1 THEN size_in_bytes ELSE 0 END) as decimal(18,2)))/1024/1024 AS [Total MBs - USE Count 1]
, sum(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END) AS [Total Plans - USE Count 1]
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER …
Run Code Online (Sandbox Code Playgroud) sql-server ×8
deadlock ×1
dimension ×1
excel ×1
parallelism ×1
plan-cache ×1
star-schema ×1
startup ×1
statistics ×1
t-sql ×1
varbinary ×1
varchar ×1
xml ×1