Questions tagged «sql-server-2008»

SQL Server 2008(主要版本10.00.xxxx)。请同时用sql-server标记。

1
计算列中使用的标量函数,更新函数的最干净方法是什么?
我想在我们的数据库中更新一个标量函数。该函数用于键表中的多个计算列,因此如果尝试更新它,则会出现依赖项错误。我可以显式删除列,更新函数并重新添加列,但是,如果没有很多多余的幻想,那将改变列顺序,并可能产生其他意想不到的后果。我想知道是否有一种更清洁的方法?

3
为什么此完全外部联接不起作用?
我之前曾使用“完全外部联接”来获得所需的结果,但也许我不完全理解该概念,因为我无法完成应该是简单联接的工作。 我有2个表(分别称为t1和t2),每个表有2个字段: 11 Policy_Number Premium 101 15 102 7 103 10 108 25 111 3 t2 Policy_Number Loss 101 5 103 9 107 20 我想做的是从两个表以及Policy_Number中获得保险费和损失总和。我使用的代码是: select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber from t1 full outer join t2 on t1.policynumber = t2.policynumber group by t1.policynumber 上面的代码将返回正确的总和,但会将“ policy_number”下“ policy_number”不匹配的所有记录分组。 我希望我的结果看起来像这样 Policy_Number Prem_Sum …

3
在表中插入数字时,如何保留前导零?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为数据库管理员Stack Exchange 的主题。 8年前关闭。 我已将两个记录插入到表中。 create table num(id int) insert into num values(0023) insert into num values(23) select * from num 当我查询它们时,它们都显示为23。这意味着SQL Server忽略前导0。其背后的机制是什么?在插入值时,SQL Server如何返回值(即0023和23)?

2
是否可以通过SQL Server 2008强制索引保留在内存中?
我有一个包含几百万行的表,我需要不时地从中运行一些查询。第一次查询通常会很慢(大约10s),而后续查询通常会更快(大约1s)。几个小时后,缓慢/快速循环又开始了。 我已经在执行计划中检查了所有需要的索引均已存在并已正确使用,并且我认为性能差异是由于该索引实际上位于后续查询的内存中(我是对的,还是其他?可能的原因?) 我还使用索引来运行许多其他查询,但是这些查询耗时较少,其性能也不太关键,因此我担心那些索引实际上会将关键索引从内存缓存中推出。 除了明显的“添加更多RAM”修复程序之外,我还一直在考虑编写脚本脚本以每小时运行一次以将索引强制返回内存。 有没有更优雅的方法可以做到这一点?就像一种提示SQLServer的方法一样,如果它只有足够的内存来保持单个索引的高速缓存,那它应该是那个? 我知道通常最好的办法是不要将SQLServer与这类事情搞混,但是我查询的异常性质(运行很少,但是时间紧迫)使我相信这样做(如果可能) 。 我也很好奇,是否有办法知道给定时间在内存中缓存了哪些索引?

2
当从带有外部参数化“ where”子句的视图中调用时,窗口函数会导致糟糕的执行计划
很久以前,我遇到了这个问题,我找到了适合自己的解决方法,却忘了它。 但是现在在SO上存在这个问题,所以我愿意提出这个问题。 有一个视图以非常简单的方式(订单+订单行)连接了几个表。 当查询不带where子句的视图时,该视图将返回几百万行。 但是,没有人会这样称呼它。通常的查询是 select * from that_nasty_view where order_number = 123456; 这将返回5m中的10条记录。 重要的是:该视图包含一个窗口函数,该窗口函数rank()完全由始终查询该视图的字段划分: rank() over (partition by order_number order by detail_line_number) 现在,如果使用查询字符串中的文字参数查询此视图(完全如上所示),它将立即返回行。执行计划很好: 使用on的索引在两个表上进行索引查找order_number(返回10行)。 在返回的微小结果上计算窗口。 选择。 但是,当以参数化方式调用视图时,情况会变得很糟: Index scan在所有表上忽略索引。返回5m行。 巨大的加入。 计算所有partitions上的窗口(约50万个窗口)。 Filter 从5m中取出10行。 选择 在涉及参数的所有情况下都会发生这种情况。可以是SSMS: declare @order_number int = 123456; select * from that_nasty_view where order_number = @order_number; 它可以是ODBC客户端,例如Excel: …

2
在IsolationLevel.ReadUncommitted上发布的共享锁
我读到,如果我使用IsolationLevel.ReadUncommitted,则查询不应发出任何锁。但是,当我对此进行测试时,看到了以下锁: 资源类型:HOBT 请求模式:S(共享) 什么是HOBT锁?与HBT(堆或二叉树锁)有关的东西吗? 为什么我还会得到S锁? 如何在不打开隔离级别快照选项的情况下进行查询时避免共享锁定? 我正在SQLServer 2008上对此进行测试,并且快照选项已设置为off。该查询仅执行选择。 我可以看到Sch-S是必需的,尽管SQL Server似乎没有在锁查询中显示它。它怎么仍然发出共享锁?根据: 设置事务隔离级别(Transact-SQL) 在该READ UNCOMMITTED级别运行的事务不会发出共享锁,以防止其他事务修改当前事务读取的数据。 所以我有点困惑。

3
通常如何存储数据库中行的每次更改的记录?
在我正在从事的项目中,必须跟踪对数据库某些表中行的每次更改,以进行进一步的审核或回滚。必须很容易找到谁修改了该行,从哪个IP地址以及何时修改了该行,并且能够还原以前的版本。 例如,Stack Exchange使用了类似的方法。当我更改其他人的问题时,可能会发现我已更改了该问题,并回滚了所做的更改。 假设我当前的架构具有与普通业务应用程序大致相同的属性(下),那么用于将每个更改存储到数据库中的对象的通用技术是什么? 对象的大小相对较小:nvarchar(1000)例如,可能会有一些,但不是很大的二进制数据斑点,该斑点直接存储在磁盘上,并且可以直接访问,而不是通过Microsoft SQL访问filestream, 数据库负载非常低,整个数据库由服务器上的一个虚拟机处理, 对先前版本的访问不必与对最新版本的访问一样快,但仍必须是最新版本¹,而又不能太慢²。 <tl-dr> 我考虑过以下情况,但是我对这种情况没有真正的经验,所以我会听到其他人的意见: 将所有内容存储在同一张表中,按ID和版本区分行。国际海事组织,这是非常愚蠢的,并且迟早会影响性能。使用这种方法,也不可能为最新项目和版本跟踪设置不同的安全级别。最后,每个查询的编写都会更加复杂。实际上,要访问最新数据,我将被迫按ID将所有内容分组并在每个组中检索最新版本。 将最新版本存储在一个表中,并在每次更改时将过时的版本复制到另一个架构中的另一个表中。缺陷在于,即使价值不变,我们每次也会存储每个价值。将不变的值设置null为并不是解决方案,因为我还必须跟踪何时将值更改为null或更改为null。 将最新版本存储在一个表中,将已更改属性及其先前值的列表存储在另一表中。这似乎有两个缺陷:最重要的是,在同一列中对异构类型的先前值进行排序的唯一方法是使用binary(max)。第二个是,我认为,在向用户显示以前的版本时,使用这种结构会更加困难。 执行与前两点相同的操作,但是将版本存储在单独的数据库中。从性能角度来看,为了避免通过在同一数据库中保留以前的版本来减慢对最新版本的访问,可能会很有趣。仍然,我认为这是一个过早的优化,只有在有证据证明在同一数据库中拥有较旧和最新版本是瓶颈时,才必须进行此优化。 </ tl-dr> ¹例如,将更改存储到日志文件中(就像处理HTTP日志一样),并在服务器负载最低的晚上将数据从日志刷新到数据库中是不可接受的。有关不同版本的信息必须立即可用或几乎立即可用;几秒钟的延迟是可以接受的。 ²信息访问频率不是很高,只有特定的用户组才能访问,但是仍然不能强迫他们等待30秒才能显示版本列表。同样,延迟几秒钟是可以接受的。

2
镜像分发服务器
有人成功镜像了分发数据库吗?我们有专用的服务器作为分发服务器。它处理我们从产品到报告的所有推式复制。我们希望在附近构建一个相同的服务器,以防分发服务器崩溃。有没有人成功建立这样的东西?




1
SQL Server 2008R2中的自动更新统计信息:尽管有大量的行插入,为什么有些统计信息仍然过时?
在调查慢速查询期间,似乎执行计划异常次优(一个嵌套循环执行900万次搜索执行,估计执行次数为1)。确认一些实际过时的相关统计数据后,我重新构建了统计数据,并且性能问题得到了有效解决。 此数据库已启用“自动更新统计信息”(默认情况下处于启用状态)。我了解根据20%+ 500行修改(更新/插入/删除)存在自动统计信息更新的阈值。在多个索引上似乎已大大超过了此阈值,因此似乎存在(A)自动更新问题或(B)更新策略的内容超出了我在网上能找到的范围文档。 我很欣赏可以设置一个计划任务来更新统计信息,如果找不到其他解决方案,这很可能是我们采用的方法,但是对于如此大量的修改为何不会触发更新,这确实使我们感到困惑。自动更新某些统计信息-了解为什么可以帮助我们确定计划任务需要更新哪些统计信息。 一些附加说明: 1)在数据库中发现了问题,该数据库中的数据是通过负载测试创建的,因此在短时间内添加了大量数据,因此,如果定期进行自动更新(例如,每天一次)大部分),则可以解释一些观察到的行为。另外,我们的负载测试往往会对数据库造成很大的压力,因此我想知道SQL是否会在负载很重的情况下推迟统计信息更新(由于某种原因随后不更新统计信息)。 2)在尝试使用包含连续的INSERT,SELECT和DELETE语句的测试脚本来重新创建此问题时,没有发生该问题。我想知道这里的区别是否在于这些语句每个都会影响每个SQL语句许多行,而我们的负载测试脚本将倾向于单独插入行。 3)有问题的数据库设置为“简单”恢复模型。 一些相关链接: 分析慢速运行查询的清单 使用统计信息来提高查询性能 我还通过Microsoft Connect提出了此问题: 自动更新统计信息:许多统计信息仍然过时 更新2011-06-30: 在进一步调查中,我认为超出阈值水平(例如500行+ 20%)的统计信息是问题查询未使用的统计信息,因此在运行查询时可能会对其进行更新。需要他们。对于查询所使用的统计信息,这些统计信息会定期更新。然后剩下的问题是,这些统计信息在仅插入了相对较少的插入次数之后(例如,导致上述900万次查找估计数量为1的情况),就严重误导了查询计划优化器。 我此时的直觉是,问题与主键选择不当有关,该键是使用NEWID()创建的唯一标识符,因此这会很快创建高度碎片化的索引-特别是作为SQL中的默认填充因子服务器是100%。我的直觉是,在相对较少的行插入之后,这会以某种方式导致统计数据产生误导-小于重新计算统计数据的阈值。这可能完全不是问题,因为我已经生成了很多数据而没有完全重建索​​引,因此,糟糕的统计信息可能是由于产生的非常高的索引碎片所致。我认为我需要将SQL Server维护周期添加到我的负载测试中,以更好地了解真实系统在长时间内的性能。 2012年1月10日更新: 要考虑的另一个因素。SQL Server 2005中添加了两个跟踪标志(2008年似乎仍然存在),以解决与过时和/或误导性统计信息的发生有关的特定缺陷。有问题的标志是: DBCC TRACEON(2389) DBCC TRACEON(2390) MSDN:Ian Jose的WebLog:升序键和升序列上的自动快速更正统计信息 统计信息,Fabiano Amorim 当然,在决定启用这些标志时应该非常小心,因为它们可能会产生不利影响。


4
优化大表上的联接
我试图从正在访问具有约2.5亿条记录的表的查询中获得更多性能。从我对实际(未估计)执行计划的阅读中,第一个瓶颈是如下查询: select b.stuff, a.added, a.value from dbo.hugetable a inner join #smalltable b on a.fk = b.pk where a.added between @start and @end; 有关所涉及的表和索引的定义,请参见下文。 执行计划表明在#smalltable上使用了一个嵌套循环,并且对largetable的索引扫描已执行480次(对于#smalltable中的每一行)。这对我来说似乎是倒退的,因此我尝试强制使用合并联接: select b.stuff, a.added, a.value from dbo.hugetable a with(index = ix_hugetable) inner merge join #smalltable b with(index(1)) on a.fk = b.pk where a.added between @start and @end; …

1
使用TDE进行数据库镜像
我需要镜像一些数据库,并在它们上使用透明数据加密(TDE),因为我们的数据必须在“静止”时进行加密。 我在主体和镜像上都设置了TDE。当我设置两个数据库的镜像时,我遇到了这个问题。由于我使用的是TDE,所以我不知道通过gui设置镜像的方法,因此我不得不使用t-sql来完成工作。 以下是我在镜像服务器上使用的代码 --Restore the full backup to the mirrored mdf and ldf OPEN MASTER KEY DECRYPTION BY PASSWORD = '1Password' RESTORE DATABASE TDE FROM disk = '\\SERVERNAME\SQL_Stuff\Backup\TDE_FULL.bak' WITH NORECOVERY, REPLACE, MOVE 'TDE' TO 'E:\TDE.mdf', REPLACE, MOVE 'TDE_log' TO 'G:\TDE.ldf' CLOSE MASTER KEY GO --Restore the log backup to the …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.