标签: sql-server

SQL Server 使用了错误的计划

在我们的应用程序中,我们有以下数据处理层:

  • .NET 编排应用程序,用于确定要触发哪些 SSIS 包
  • 完成大部分工作并调用存储过程的 SSIS 包
  • 用于在 SSIS 数据流不合适的情况下执行计算和读/写数据的存储过程

如果从 SSMS 执行,一个存储过程将在 40 秒内运行,如果手动调用 SSIS 包,则大约在同一时间运行。

但是,如果 SSIS 包由 .NET 应用程序调用,则查询需要超过 14 小时才能运行,并且所有处理器都排平。

查看执行计划,似乎如果从 SSMS 运行该过程或手动触发 SSIS 包然后调用该过程,SQL Server 将使用基于当前统计数据的合理计划。

但是,如果从 .NET 应用程序调用 SSIS 包,则 SQL Server 会创建一个新计划,使用完全错误的统计信息。以下事情没有区别:

  • 更新统计
  • 清除缓存
  • 重启实例
  • 在过程执行中设置 WITH RECOMPILE

我们通过在查询中使用 MAXDOP 提示来伪造分辨率,但我的问题是:

当通过我描述的方法使用相同的参数和相同的数据调用时,基于完全不正确的统计信息,什么会使 SQL Server 产生完全不同的计划?

sql-server

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

更改为静态端口的影响

我目前有一个 SQL Server 托管两个生产实例,其中有许多 Web 应用程序可以访问它们。据我所知,这些应用程序都没有在其连接字符串中使用特定端口,我也不知道这是否重要。

我的问题是,将这些实例分配给静态端口有什么含义?这会破坏我的应用程序吗?在执行此操作之前,我还需要进行或考虑其他调整吗?

问的原因?我的基础架构团队要求我分配静态端口,以便为受限委派权限分配 SPN。谢谢。;)

sql-server

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

能否将这个 SQL 提高效率并组合成一个选择?

我有下面的 4 个 SQL 查询,最后我将它们组合成一个结果集。

我猜是因为我在每个 SQL 部分都对相同的表进行操作,所以有一种很酷的方法可以从一个统一的 SQL 查询中获取我的结果。

目前我是这样做的:

select 
[date] = CONVERT(DATE, M.crdate), 
[tally sent to smc w/ attachment] = count(*) ,
[total MB size] =  sum(cast(AD.Size as decimal (10,2)) )/1024/1024 
into #tmp_Attachments_Sent_To_smc
from AttachmentDetail AD
inner join MessageAttachment MA on AD.AttachmentId = MA.AttachmentId
inner join MessageRecipient MR on MA.MessageId = MR.MessageId 
inner join Message M on MR.MessageId = M.id
where AD.isinline <>1 and MR.RecipientTypeId =2 and left(mr.EmailAddress,4)='smc+' 
GROUP BY  CONVERT(DATE, M.crdate)
ORDER BY [date] DESC;
--select …
Run Code Online (Sandbox Code Playgroud)

sql-server

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

sql脚本中的foreach循环?

在 powershell 中,我用来foreach通过目标列表运行一个函数。

我想知道是否有任何类似于foreachsql 的东西,所以我可以通过我选择的多个数据库运行相同的查询并将结果保存到一个 csv 文件?

sql-server t-sql csv

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

为混合 Always on Environment+ 实例创建 Windows 登录/用户,而无需 Always ON

我如何通过更改以下脚本来在启用/未启用 Always ON 的环境中运行。在 Kin 提供了一些非常有用的建议之后,下面似乎正在起作用。但是,当我需要跨 300-400 个 SQL 服务器进行部署时,此代码肯定不会处于最佳状态,而有些总是在其他服务器上没有。

请帮我修改/检查实例是否启用了AG并成功执行

更新根据@Kin 的要求

SET NOCOUNT ON   

 DECLARE @user_to_be_added sysname  
 SET @user_to_be_added = 'Domain\user'  

 DECLARE @sqltext nvarchar(max) = N''  

     if (select serverproperty('IsHadrEnabled')) = 0

  BEGIN

           -- change  to your user to be added .. make sure that the login is already existing

       SELECT  @sqltext += char(10)+ 'use '+quotename(name)+';'+char(10)+ 'CREATE USER '+quotename(@user_to_be_added)+' FOR LOGIN '+quotename(@user_to_be_added)

       FROM sys.databases where state_desc ='ONLINE' AND databaseproperty(name,'isReadOnly') = 0 

       SELECT  @sqltext

 END

    Else

 BEGIN


      SELECT  @sqltext …
Run Code Online (Sandbox Code Playgroud)

sql-server availability-groups sql-server-2014 sql-server-2016

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

单个数据库的两个日志文件

在单个数据库和不同驱动器上拥有两个日志文件是否有任何原因或性能优势?

sql-server

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

为什么 sqlexpress 在 .\sqlexpress 上运行而 mssqlserver 在 .\ 上运行

我有两台电脑。

一台机器运行sqlexpress,实例名为SQLEXPRESS

另一台机器运行 mssqlserver,实例是 MSSQLSERVER。

为什么 sqlexpress 在 .\sqlexpress 上运行而 mssqlserver 只在 .\ 上运行?

sql-server sql-server-2012

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

将 SQL Server 结果转换为 PowerShell 可以访问和使用的文本文件

下面的查询用于创建一个带有服务器名称列表的文本文件。

我遇到的问题是文本文件的创建就像

Server, Server, Server etc.
Run Code Online (Sandbox Code Playgroud)

但我需要它如下

Server
Server
Server
Run Code Online (Sandbox Code Playgroud)

查询:

BEGIN
    CREATE TABLE [TempPSWmiObjectQuery]
                (QueryText nvarchar(max))
END

INSERT INTO [TempPSWmiObjectQuery]

SELECT STUFF((SELECT char(13)+char(10), 
             SUBSTRING(ServerName, 1, 
             CASE WHEN CHARINDEX(',', ServerName) > 0 
                  THEN CHARINDEX(',', ServerName)-1
                  ELSE LEN(ServerName)
             END)
FROM MasterList
FOR XML PATH('')), 1, 1, '')

EXEC sp_configure 'xp_cmdshell', 1;  
RECONFIGURE

EXEC xp_cmdshell 'bcp SQLEnv.dbo.TempPSWmiObjectQuery out "\\ServerName\Data\temp\testlist.txt" -c -T -S "ServerName\Instance"'

EXEC sp_configure 'xp_cmdshell', 0;  
RECONFIGURE

DROP TABLE TempPSWmiObjectQuery
Run Code Online (Sandbox Code Playgroud)

PowerShell 脚本:

        $StagingServer = "ServerName\InstanceName"
        $StagingServerDatabase = "SQLEnv" 

    foreach($line in 
    [System.IO.File]::ReadLines("\\ServerName\Data\temp\testlist.txt")) …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server powershell sql-server-2008-r2 sql-server-2012

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

实施 ISCSI SAN 固态驱动器时,对基于成本的优化器 (CBO) 有何影响

Microsoft Technet 文章建议将辅助文件组创建为默认文件组(请参阅下面的参考)。辅助文件组应该有多个文件,比如四个,每个文件都放在不同的磁盘上。作为同事的补充经验法则,文件数应等于 CPU 内核数。

我的理解是,这种设置非常适合机械旋转磁盘驱动器,因为旋转磁盘驱动器比固态驱动器慢得多,因此可以通过从多个磁头流式传输数据来提高性能。这种理解是否正确?

如果是,那么我的问题是基于成本的优化器是否考虑了较新的固态驱动器?当切换到新的固态驱动器时,旋转硬盘驱动器的性能瓶颈似乎消失了。我们的 IT 运营小组告诉我,虽然我目前被分配了一个虚拟驱动器,但数据实际上存储在 ISCSI SAN 上,它有多个固态驱动器。

这个问题旨在回答对于这种规模的大型数据库来说,最佳设置是什么:

  1. 我应该有一个只有一个文件的默认辅助文件组吗?
  2. 我是否应该有一个默认的辅助文件组,其中包含的文件数等于 CPU 上的内核数?
  3. 使用固态驱动器时对数据库表进行分区是否可以提高性能?

我正在处理的当前项目需要一个可扩展的数据库,该数据库的大小将达到几 TB,用于存储大量日志数据。一周的样本大约有 1.5 亿条记录,我们需要存储 3 年的滚动日志。所以,我现在正在寻找长时间运行的查询来查找数据。我已经将索引调整到几乎所有工作都归因于非聚集索引搜索的程度;优化器不建议添加缺失的索引。

笔记

Microsoft SQL Server 上的许可目前由 CPU 内核决定。因此,在这个问题上投入更多内核是很敏感的,尤其是在这不会提高性能的情况下。

此外,我目前正在 SQL Server 2014 上进行开发,但将迁移到 SQL Server 2017 进行开发和生产。

更新 1

该项目将每晚加载日志,我预计很少(可能没有)更新或删除,因为日志根本不会改变 - 所以它们不会被重新加载。出于分析目的,将读取其他所有内容。

系统表的 PRIMARY 文件组,其中 SECONDARY 默认文件组用于其他所有内容。这样做的原因由本问题底部引用的链接解释。

将为表分区创建单独的文件组。数据库中还有其他足够小的表,它们将驻留在 SECONDARY 文件组中 - 我只对两个表进行分区,其中一个超过 1 亿条记录(按 IDENTITY 行号分区),另一个将进入数十亿条记录(按时间划分[每月])。

我计划在 3 年内按月进行分区。因此,将有 36 个分区。我将为每年创建文件组,然后将 12 个文件放入相应的年度文件组中。分区策略是为了减少读取时间,因为会有大量数据扫描用于分析目的。年度文件组策略严格来说是为了便于 DBA 维护,他们可以通过删除单个文件组来删除一年的数据。

参考:

SQL Server 最佳实践设置默认文件组

sql-server optimization filegroups partitioning configuration

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

记录到文件

我正在使用 ola-hallengren 维护脚本。我正在登录到表和文件。我想更改文件日志的位置。我可以这样做吗?非常感谢

sql-server maintenance-plans ola-hallengren

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