数据库管理员

希望提高数据库技能并向社区中的其他人学习的数据库专业人员的问答


2
为什么DELETE查询以一种格式运行的时间要长于另一种格式?
我有特定的清理代码,试图删除一些重复项。 它可以在许多客户站点上完美运行。日志告诉我,此查询至少消耗1秒到45秒: DELETE FROM [tbl] WHERE [Id] NOT IN ( SELECT MIN([Id]) FROM [tbl] GROUP BY [IdProject], [IdRepresentative], [TimeStart] ) 但是我有一个客户,该查询运行了4个多小时(到现在为止还没有结束)!我检查了数据库(DBCC CHECKDB),我已经更新了统计信息(sp_updatestats),也UPDATE STATISTICS [tbl] WITH FULLSCAN没有显示任何更改。 我有客户的数据库原始备份。我在SQL Server 14.0.2002.14上运行它。我有标准版,客户使用Express Edition。 我可以在活动监视器中看到没有其他人正在使用该数据库。无需等待,CPU使用率达到25%(恰好是我4个CPU中的1个)。同样在这个测试用例中,没有其他人正在使用数据库。 我重新设计了查询并检查了以下语句: DELETE FROM [tbl] FROM [tbl] AS t LEFT OUTER JOIN ( SELECT MIN([Id]) AS [IdMin] FROM [tbl] GROUP …

2
为什么我将Int / Smallint隐式转换为Varchar,这真的会影响基数估计吗?
我正在尝试使用实际执行计划上的“显示计划分析”(SSMS)来执行性能缓慢的查询。分析工具指出,行数的估计值与计划中某些位置的返回结果不符,并进一步给了我一些隐式转换警告。 我不理解这些从int到Varchar的隐式转换-引用的字段不是查询中任何参数/过滤器的一部分,并且在涉及的所有表中,列数据类型都是相同的: 我收到以下CardinalityEstimate警告: 表达式中的类型转换(CONVERT_IMPLICIT(varchar(12),[ccd]。[profileid],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我的数据库中到处都是整数 表达式中的类型转换(CONVERT_IMPLICIT(varchar(6),[ccd]。[nodeid],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我数据库中的每个地方都是smallint 表达式中的类型转换(CONVERT_IMPLICIT(varchar(6),[ccd]。[sessionseqnum],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我的数据库中到处都是smallint 表达式中的类型转换(CONVERT_IMPLICIT(varchar(41),[ccd]。[sessionid],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我的数据库中到处都是小数 [编辑]这是查询和实际执行计划,以供参考 https://www.brentozar.com/pastetheplan/?id=SysYt0NzN 和表定义 /****** Object: Table [dbo].[agentconnectiondetail] Script Date: 1/10/2019 9:10:04 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[agentconnectiondetail]( [sessionid] [decimal](18, 0) NOT NULL, [sessionseqnum] [smallint] NOT NULL, [nodeid] [smallint] NOT NULL, [profileid] [int] …

4
标识栏重新设置种子:何时需要?
在大学的最后一课中(我是学生),讲师要求我们开发数据库(如果重要的话,请使用MySQL Server)和小型客户端应用程序,该应用程序会将数据库用作数据源。 要求之一是,身份列(每个表中的PK)必须是顺序的,因为这是一种好习惯(按照讲师的话)。也就是说,当删除表行时,必须在后续插入中重用它的PK。我对RDBMS,PK和标识列有一般的了解。据我了解,标识列只是让数据库在插入行时自动生成PK的一种方式。标识列值不得以任何方式与行属性相关(只要它不是自然键即可)。 这个要求(严格按照顺序标识列)对我来说是可疑的。我试图问讲师,如果身份不是顺序的(由于删除引起的空白),那又有什么问题,但是却得到了非常抽象的答案,例如“它对用户方便,对维护数据库的数据库管理员有用”。没有具体的例子。“方便用户”这一说法听起来很愚蠢,因为它在业务领域没有任何意义。 因此,我很好奇这些原因是否真实?我只想到一种情况,即需要重新分配标识列种子时–当标识空间用尽时。但是,当标识列类型选择不正确时,例如用“ simple” int代替,bigint或者uniqueidentifier表包含十亿行时,这将是更多的设计问题。假设身份列是聚集索引:身份列中的间隙会影响索引性能吗?也许还有其他现实原因导致我不知道的每次删除后重新自动标识列的种子? 提前致谢!

1
为什么批处理模式窗口合计会产生算术溢出?
以下查询在具有SUM的列存储表上执行带窗口的窗口1500 total rows,每个表的值均为0或1,并且溢出INT数据类型。为什么会这样呢? SELECT a, p, s, v, m, n, SUM(CASE WHEN n IS NULL THEN 0 ELSE 1 END) OVER (PARTITION BY s, v, a ORDER BY p) AS lastNonNullPartition FROM ( SELECT a, p, s, v, m, n, RANK() OVER (PARTITION BY v, s, a, p ORDER BY …

1
从视图中选择*需要4分钟
我遇到一个问题,当我针对视图运行查询时,它需要4分钟以上的时间。但是,当我运行查询的内容时,它会在大约1秒钟内完成。 我唯一不确定的是要联接的表都是临时表。 临时查询计划:https : //www.brentozar.com/pastetheplan/?id=BykohB2p4 查看查询计划:https : //www.brentozar.com/pastetheplan/?id=SkIfTHh6E 关于在哪里尝试找出答案的任何建议? 查看代码: ALTER VIEW [dbo].[vwDealHistoryPITA] AS SELECT ROW_NUMBER() OVER (PARTITION BY cm.CodeMasterID ORDER BY cm.CodeMasterID, cm.LastUpdateDate) AS Deal_HistoryID, cm.CodeMasterID, cm.ProjectName, cm.[Status], d.CompanyID, d.DealTypeMasterID, cm.[Description], d.PassiveInd, d.ApproxTPGOwnership, d.NumberBoardSeats, d.FollowonInvestmentInd, d.SocialImpactInd, d.EquityInd, d.DebtInd, d.RealEstateInd, d.TargetPctgReturn, d.ApproxTotalDealSize, cm.CurrencyCode, d.ConflictCheck, cm.CreatedDate, cm.CreatedBy, cm.LastUpdateDate, cm.LastUpdateBy, d.ExpensesExceedThresholdDate, d.CurrentTPGCheckSize, …
11 sql-server 

1
列出特定表的ROW_OVERFLOW_DATA页
我正在尝试获取具有ROW_OVERFLOW_DATA行的表的页面列表。我可以从未记录的DMV中获得分配页面的列表sys.db_db_database_page_allocations,但是,该DMV的输出中似乎没有列出ROW_OVERFLOW_DATA页面。还有我无法找到的其他DMV吗? 最小,完整和(希望!)可验证的示例: USE tempdb; IF OBJECT_ID(N'dbo.t', N'U') IS NOT NULL DROP TABLE dbo.t; GO CREATE TABLE dbo.t ( rownum int NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED , on_row_data varchar(30) NOT NULL DEFAULT ('on_row_data') , off_row_data varchar(MAX) NOT NULL DEFAULT REPLICATE('A', 20000) --PLENTY BIG ENOUGH! ) WITH (DATA_COMPRESSION = NONE); --not …

2
MAXDOP = 1,并行查询提示和成本阈值
如果实例MAXDOP设置为1,并且查询提示用于允许特定查询并行进行,那么SQL仍然使用“并行成本阈值”来决定是否实际并行吗? 尽管此链接建议CTFP如果MAXDOP为1 ,则将其忽略。尽管有任何查询,无论成本如何,在没有查询提示的情况下,当MAXDOP值为1 时,它都将并行进行。 谁能让我知道这两个请求的预期行为? 范例1: Instance Maxdop: 1 CTFP: 50 Query hint: Maxdop=2 Query cost: 30 范例2: Instance Maxdop: 1 CTFP: 50 Query hint: Maxdop=2 Query cost: 70

1
N'Șc'使用Latin1_General_CI_AS排序规则将N'C'的重复密钥视为
我有一个带有唯一键的表,该键包括一NVARCHAR(50)列(是否正确,但在那里)。因此,当尝试插入Șc或C(与插入顺序无关)时,由于排序规则问题,它在第二个插入处中断。这是错误: (受影响的1行)消息2601,级别14,状态1,行16无法在具有唯一索引'IX_TestT'的对象'dbo.testT'中插入重复的键行。重复的键值为(C)。 选择返回: 数据库默认排序规则为Latin1_General_CI_AS。花了一些时间研究如何解决该问题,而又没有太大改变现有的结构,但是找不到找到工作的方法。尝试了不同的排序规则和组合,一切都失败了。阅读(此处和此处)有关字符扩展等方面的信息,但仍然受阻。这是我用来复制问题的示例代码,可以随时进行修改并提出可以帮助解决此问题的任何建议。 CREATE TABLE testT ( [Default_Collation] [NVARCHAR] (50) COLLATE DATABASE_DEFAULT, [Latin1_General_CI_AS] [NVARCHAR] (50) COLLATE Latin1_General_CI_AS, [Latin1_General_CI_AI] [NVARCHAR] (50) COLLATE Latin1_General_CI_AI, [SQL_Collation] [NVARCHAR] (50) COLLATE SQL_Latin1_General_CP1_CI_AS); CREATE UNIQUE CLUSTERED INDEX [IX_TestT] ON [dbo].[testT] ([Default_Collation]) ON [PRIMARY] GO INSERT INTO testT SELECT N'Șc', --COLLATE Latin1_General_CI_AS N'Șc', --COLLATE Latin1_General_CI_AS N'Șc', …

1
为什么NOLOCK会使具有变量分配的扫描变慢?
在当前环境下,我正在与NOLOCK作战。我听到的一个论点是,锁定的开销会使查询变慢。因此,我设计了一个测试以查看此开销可能是多少。 我发现NOLOCK实际上减慢了我的扫描速度。 起初我很高兴,但是现在我很困惑。我的考试以某种方式无效吗?NOLOCK实际上不应该允许扫描速度稍快吗?这里发生了什么事? 这是我的脚本: USE TestDB GO --Create a five-million row table DROP TABLE IF EXISTS dbo.JustAnotherTable GO CREATE TABLE dbo.JustAnotherTable ( ID INT IDENTITY PRIMARY KEY, notID CHAR(5) NOT NULL ) INSERT dbo.JustAnotherTable SELECT TOP 5000000 'datas' FROM sys.all_objects a1 CROSS JOIN sys.all_objects a2 CROSS JOIN sys.all_objects a3 /********************************************/ …

2
SQL Server数据库何时准备好接受查询?
在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'. 如果在此之前我检查数据库XYZ的状态,则ONLINE使用以下语句: SELECT state_desc FROM sys.databases WHERE name='XYZ' ...但是当我尝试使用C#应用程序连接到该数据库时,它无法连接到数据库。 错误是: 用户“ asd”的登录失败。 原因:无法打开显式指定的数据库。 我尝试了三种不同的用户(Windows用户,sa,为应用程序定义的SQL Server用户)。在操作系统启动时运行该应用程序时会发生问题,但是如果在启动后手动启动该应用程序,则不会发生任何错误,因此我认为所有SQL Server设置和防火墙设置都是正确的。 在此之前,我还检查了服务状态是否正在运行。 我还应该检查什么以确保数据库实际上已联机并且可以查询? 我正在寻找一个可以告诉我可以查询数据库的键,而不是延迟一段时间(即使不是基于明确的原因)。 我考虑过扫描错误日志中的文本“正在启动数据库XYZ”,但这意味着我必须为SQL Server错误日志的路径为应用程序添加一个设置。这也意味着要多次读取文件,直到找到该短语。

3
授予ALTER TABLE权限有多危险?
想象以下情况 CREATE DATABASE test GO USE test; CREATE TABLE dbo.Customer ( CustomerId INT, Email VARCHAR(100), SensitiveData VARCHAR(20) ); INSERT INTO dbo.Customer VALUES (1,'abc@foo.com','12346789'); 在某个时候,编写了一个ETL过程,该过程在test数据库中执行某些活动。 CREATE USER etlUser WITHOUT LOGIN; /*For demo purposes*/ CREATE TABLE dbo.StagingTable ( StagingTableId INT, SomeData VARCHAR(100), ) GRANT UPDATE,INSERT,DELETE,SELECT,ALTER ON dbo.StagingTable TO etlUser; DENY SELECT ON …

2
SELECT和WHERE子句中的功能相同
初学者问题: f(x, y)我的数据库表中的x和y两列都有一个昂贵的函数。 我想执行一个查询,该查询将函数的结果作为列提供给我,并对其施加约束,例如 SELECT *, f(x, y) AS func FROM table_name WHERE func < 10; 但是,这不起作用,所以我将不得不写一些类似的东西 SELECT *, f(x, y) AS func FROM table_name WHERE f(x, y) < 10; 这会运行两次昂贵的功能吗?最好的方法是什么?

5
如何将case语句中的100个以上的条目作为变量
我编写了一个包含100多个选择的case语句,在一个简单的查询中,我在4个地方使用同一条语句。 相同的查询两次,并且它们之间有一个并集,但也进行计数,因此group by还包含case语句。 这是为了重新标记某些公司名称,其中同一公司的不同记录的拼写不同。 我试图将变量声明为VarChar(MAX) declare @CaseForAccountConsolidation varchar(max) SET @CaseForAccountConsolidation = 'CASE WHEN ac.accountName like ''AIR NEW Z%'' THEN ''AIR NEW ZEALAND'' WHEN ac.accountName LIKE ''AIR BP%'' THEN ''AIR BP'' WHEN ac.accountName LIKE ''ADDICTION ADVICE%'' THEN ''ADDICTION ADVICE'' WHEN ac.accountName LIKE ''AIA%'' THEN ''AIA'' ... 当我在select语句中使用它时-查询仅将case语句返回为文本,并且未对其进行评估。 我也无法在群组中使用它-我收到此错误消息: Each GROUP BY …

1
什么函数在SQL Server的dynamic-sql中引用标识符?
用于动态sql生成的SQL Server安全引用标识符的方法是什么。 MySQL有 quote_identifier PostgreSQL有 quote_ident 如何确保给定动态生成的语句的动态生成的列名称,该列本身不是SQL注入攻击。 假设我有一条SQL语句, SELECT [$col] FROM table; 基本上与 'SELECT [' + $col + '] FROM table;' 什么阻止了注射攻击 $col = "name] FROM sys.objects; \r\n DROP TABLE my.accounts; \r\n\ --"; 导致 SELECT [name] FROM sys.objects; DROP TABLE my.accounts; -- ] FROM table;

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.