标签: sql-server

末尾有空格的 Varchar 的行为

当我使用带有空格的 Varchar 时,它会忽略末尾的空格。

前任:

declare @X varchar(50)
Run Code Online (Sandbox Code Playgroud)

这个...

set  @X= 'John'
Run Code Online (Sandbox Code Playgroud)

...是相同的...

set @X= 'John           '
Run Code Online (Sandbox Code Playgroud)

它认为这些是相等的。我怎样才能让系统将这些识别为不同的?

sql-server stored-procedures

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

SQL Server 链接服务器性能:为什么远程查询如此昂贵?

我有两个数据库服务器,通过链接服务器连接。两者都是 SQL Server 2008R2 数据库,链接服务器连接是通过常规“SQL Server”链接使用当前登录的安全上下文建立的。链接的服务器都在同一个数据中心,所以连接应该不是问题。

我使用以下查询来检查列的哪些值identifier可远程使用,但不能在本地使用。

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT DISTINCT
    identifier 
FROM LocalDb.schema.[TableName] 
Run Code Online (Sandbox Code Playgroud)

在两个表上的列上都有非聚集索引identifier。本地大约有 260 万行,远程只有 54 行。然而,在查看查询计划时,70% 的执行时间用于“执行远程查询”。此外,在研究完整的查询计划时,估计的本地行数是1而不是2695380(这是仅选择后面的查询时的估计行数EXCEPT)。 执行计划 执行此查询时,确实需要很长时间。

不禁让人疑惑:这是为什么呢?估计是“刚刚”结束,还是链接服务器上的远程查询真的那么昂贵?

sql-server sql-server-2008-r2 linked-server except

16
推荐指数
2
解决办法
4万
查看次数

这些表设计中哪一个更能提高性能?

我被要求创建一些东西来跟踪每天收取的帐户成本,我正在尝试找出一个支持这一点的数据库表模式。

这是我所知道的

  • 公司拥有超过 250 万个账户
  • 其中,他们目前平均每月工作 200,000 人(随着人员配备水平而变化,目前处于较低水平)
  • 他们有 13 种不同的成本类型要跟踪,并且警告说将来可能会增加更多
  • 他们希望每天跟踪成本
  • 成本不会在整个库存中分摊。它们要么分布在每月工作的帐户数量 (200,000) 中,要么用户可以输入帐户标识符以将成本应用于一组帐户,或者他们可以简单地指定将成本应用于哪些帐户。

我的第一个想法是标准化数据库:

帐户ID
日期
成本类型 ID
数量

我的问题是,做数学。这张桌子很快就会变大。假设所有 13 种成本类型都应用于当月的所有工作帐户,即每月200k * 13 * N days in month大约 75-8000 万条记录,或接近每年 10 亿条记录。

我的第二个想法是对其进行非规范化

帐户ID
日期
总消耗
成本类型 1
成本类型2
成本类型 3
成本类型 4
成本类型5
成本类型 6
成本类型7
成本类型8
成本类型9
成本类型10
成本类型11
成本类型12
成本类型13

这种方法更加非规范化,每月最多可创建 600 万条记录 ( 200k * N days in month),或每年约 7200万条。它比第一种方法少很多,但是如果公司将来决定使用新的成本类型,则需要添加另一个数据库列。

在这两种方法中,您更喜欢哪种方法?为什么?您是否可以想到另一种替代方法可以更好地处理此问题?

我对报告绩效最感兴趣,包括总结报告和详细报告。将成本分摊到帐户的工作将在无人在场的情况下每晚运行。次要问题是数据库大小。现有的数据库已经接近300GB,我相信磁盘空间在500GB左右。

数据库是 SQL Server 2005

performance database-design sql-server

16
推荐指数
2
解决办法
534
查看次数

使用动态sql在指定的数据库中创建视图?

我正在编写一个动态 sql 以在不同的数据库中删除和创建视图。

所以我写道:

set @CreateViewStatement = 
                '
                USE ['+ @DB +'];
                CREATE VIEW [dbo].[MyTable]
                AS

                SELECT ........something
exec (@CreateViewStatement)
Run Code Online (Sandbox Code Playgroud)

它给了我错误:

'CREATE VIEW' 必须是查询批处理中的第一条语句。

如果我删除 USE DATABASE 语句,它可以正常工作,但是不再指定数据库....

我怎么解决这个问题?

sql-server-2005 sql-server dynamic-sql

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

大索引 INCLUDE 字段将如何影响系统性能?

这个问题是关于 SQL Server 索引性能,a varchar(2000)as an INCLUDEin a coverage index。

我正在尝试提高缓慢且不稳定的数据库应用程序的性能。在某些情况下,数据是通过大VARCHAR字符串来访问的,与查询包括像multple字符串操作SUBSTRING(),SPACE()和DATALENGTH()。这是访问的简化示例;

update fattable set col3 =  
   SUBSTRING(col3,1,10) + '*' + 
   SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2
Run Code Online (Sandbox Code Playgroud)

架构如下所示:

CREATE TABLE [dbo].[FatTable]( 
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [col1] [nchar](12) NOT NULL, 
    [col2] [int] NOT NULL, 
    [col3] [varchar](2000) NOT NULL, ... 
Run Code Online (Sandbox Code Playgroud)

定义了以下索引,在大文本列上有一个覆盖字段。

CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable]  ( [col2] ASC ) 
    INCLUDE( [col3] )
Run Code Online (Sandbox Code Playgroud)

从我读过的内容来看,将大数据字段放在索引中是很糟糕的。我一直在阅读几篇文章,包括http://msdn.microsoft.com/en-us/library/ms190806.aspx,其中讨论了分页和磁盘大小对索引性能的影响。话虽如此,查询计划肯定会使用覆盖索引。我没有足够的信息来确定这在系统负载方面实际上给我带来了多少成本。我确实知道总体而言,系统性能不佳,我担心这是问题之一。问题:

  • 将此varchar(2000) …

performance sql-server-2008 sql-server index-tuning

16
推荐指数
2
解决办法
4095
查看次数

使用 RECOMPILE 查询提示时查询之间的执行时间存在巨大差异

我有两个几乎相同的查询在同一个 SQL Server 2005 实例上运行:

  1. 第一个是SELECT由 LINQ 生成的原始查询(我知道,我知道......我不是应用程序开发人员,只是 DBA :)。
  2. 第二个和第一个完全一样,OPTION (RECOMPILE)在最后加了一个。

没有其他任何改变。

第一个每次运行需要 55 秒。
第二个需要 2 秒。

两个结果集是相同的。

为什么这个提示会产生如此显着的性能提升?

在线图书条目RECOMPILE没有提供非常详细的解释:

指示 SQL Server 数据库引擎在执行后放弃为查询生成的计划,强制查询优化器在下次执行相同查询时重新编译查询计划。在不指定 RECOMPILE 的情况下,数据库引擎会缓存查询计划并重用它们。编译查询计划时,RECOMPILE 查询提示使用查询中任何局部变量的当前值,如果查询在存储过程中,则将当前值传递给任何参数。

RECOMPILE 是创建使用 WITH RECOMPILE 子句的存储过程的一种有用的替代方法,当必须重新编译存储过程中的查询子集而不是整个存储过程时。有关详细信息,请参阅重新编译存储过程。RECOMPILE 在您创建计划指南时也很有用。有关更多信息,请参阅使用计划指南优化已部署应用程序中的查询。

由于我的查询有很多局部变量,我的猜测是当我使用OPTION (RECOMPILE)查询提示时,SQL Server 能够(认真地)优化它。

我所看到的每个地方都有人说OPTION (RECOMPILE)应该避免这种情况。对此的解释通常是使用此提示 SQL Server 无法重用此执行计划,因此每次都必须浪费时间重新编译它。
(但是)考虑到巨大的性能优势,我倾向于认为这次使用这个查询提示会是一件好事。

我应该使用它吗?如果没有,有没有一种方法可以强制 SQL Server 使用更好的执行计划而无需此提示且无需更改应用程序?

performance sql-server-2005 sql-server optimization query-performance

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

在哪里学习 SQL Server Service Broker?

是否有学习 Service Broker 的好资源?我正在寻找对新手友好的指南。

sql-server service-broker sql-server-2012

16
推荐指数
2
解决办法
2372
查看次数

如果不存在,则通过代码创建新函数

我想在我的数据库中通过脚本创建新函数。脚本代码如下:

IF Exists(Select * From sys.sysobjects A Where A.name =N'fn_myfunc' and xtype=N'FN') return;

CREATE FUNCTION fn_myfunc ()
returns varchar(10)
AS Begin
...
End
Run Code Online (Sandbox Code Playgroud)

但是当我执行上面的脚本时,SQL Server 返回一个错误:

'CREATE FUNCTION' must be the first statement in a query batch.
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2008-r2 functions

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

分页时 SQL Server 查询速度变慢

我在 SQL Server 2012 中看到以下 T-SQL 查询的一些奇怪行为:

SELECT Id 
FROM dbo.Person 
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Run Code Online (Sandbox Code Playgroud)

单独执行这个查询在不到两秒的时间内给了我大约 1,300 个结果(有一个全文索引Name)

但是,当我将查询更改为:

SELECT Id 
FROM dbo.Person 
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

给我10个结果需要20多秒。

下面的查询更糟糕:

SELECT Id 
FROM ( 
    SELECT ROW_NUMBER() OVER (ORDER BY Name) AS RowNum, Id 
    FROM dbo.Person
    WHERE CONTAINS(Name, '"John" AND "Smith"') ) AS RowConstrainedResult 
WHERE RowNum >= 0 AND RowNum < 11 
ORDER BY …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2012

16
推荐指数
2
解决办法
5646
查看次数

为什么以不允许在大多数子句中使用列别名的方式解析查询?

在尝试编写查询时,我发现(困难的方法)SQL Server 在执行查询时解析 SELECT 之前很久就解析了查询中的 WHERE。

的MSDN文档说,一般逻辑解析顺序是这样的:SELECT被解析几乎最后(因此导致“没有这样的对象[别名]”试图使用在其他条款列别名时误差)。甚至有人建议允许在任何地方使用别名,但被微软团队驳回,理由是 ANSI 标准合规性问题(这表明这种行为是 ANSI 标准的一部分)。

作为一名程序员(不是 DBA),我发现这种行为有些令人困惑,因为在我看来它在很大程度上违背了拥有列别名的目的(或者,至少,如果列别名是在查询执行中更早地解析),因为您可以实际使用别名的唯一地方是在 ORDER BY 中。作为一名程序员,它似乎错过了使查询更强大、更方便和 DRY 的巨大机会。

看起来这是一个如此明显的问题,它有理由认为,除了 SELECT 和 ORDER BY 之外,还有其他原因决定不允许列别名,但这些原因是什么?

sql-server alias

16
推荐指数
2
解决办法
3293
查看次数