数据库管理员

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


2
SQL Server:是否涵盖所有列的索引?
我们的团队继承了一个应用程序和关联的数据库。以前的开发人员似乎执行了一个规则,即每个表上的每个索引都有一个INCLUDE子句,以始终添加不属于键一部分的每个列。这些表平均具有2到5个索引或唯一约束以及外键。 目的是不管在数据库上引发什么查询,都是为了提高SELECT性能,因为访问是通过默认(但并非总是)检索所有列的ORM进行的。我们希望这样做的副作用是增加了存储需求(可能如此),并且增加了INSERT / UPDATE / DELETE的开销时间。 问题是,这是明智的策略吗?我们的团队具有SQL Server的历史,但是没有成员会认为自己是其内部行为的专家(尽管已经提出了一个问题,即如果该策略是最佳策略,那么现在是否将其作为默认策略?)。我们还应该期待其他哪些副作用(数据库服务器CPU /内存/ TempDB的使用情况等),或者上述某些假设是否正确? 此外,该应用程序既可以安装到SQL Server内部部署(自2012年以来的版本)中,也可以安装到Azure SQL中-如果我们为两者之间的任何差异或Azure的其他副作用做好了准备,方法?

1
SQL每隔几分钟就会从缓冲区缓存中转储所有页面
我有一个运行多个数据库的SQL2012 SP4节点。 该服务器有20GB可用内存,已为SQL分配了14GB内存(包装盒上没有其他任何东西)。 SQL每隔几分钟就会转储整个缓冲区高速缓存。页面预期寿命为零,缓冲区高速缓存描述符显示高速缓存中没有任何内容。 我查看了资源监视器通知,并且通知每隔几毫秒从高/稳定/低反弹一次: RESOURCE_MEMPHYSICAL_LOW RESOURCE_MEM_STEADY RESOURCE_MEMPHYSICAL_LOW 时间戳相隔几毫秒。PLE本质上是锯齿形。 我已经在SQL2012 SP1和以下问题之前看到过这种情况: 未使用缓冲区高速缓存中的SQL Server 2012可用页 似乎是类似的问题,尽管我已经更新到SP4。 我尝试为该服务帐户打开LPIM,并且尝试弄乱最大内存设置。降低最大内存似乎已导致缓冲区缓存更频繁地清空。 关于下一步要检查的任何想法? 服务器工作负载实际上什么都没有(我正在滚动浏览ERP系统中的项目列表,在缓存再次下降之前,它达到了40-50MB)。 这很有趣,因为我从SP1升级以尝试解决此问题-那里的缓存已达到500MB左右。从那以后,我将最大内存设置降低到14GB,这似乎使情况变得更糟。 我想知道Windows是否惊慌并在SQL上发出有关内存压力的不正确通知-随之而来的是,将最大内存设置为无界的服务器似乎运行正常,但永远不会填满超过几百MB的缓存-但现在它刚到50岁... 更多信息:对于那些询问 核心数: 4 数据库大小: 80GB 错误日志显示: A significant part of sql server process memory has been paged out. This may result in a performance degradation. Duration: 0 seconds. Working set …

2
计算列无法保留,因为该列是不确定的
我知道这不是第一次提出此类问题。 但是,为什么在以下情况下创建的持久化计算列是“不确定的”。答案应该总是一样的,对不对? CREATE TABLE dbo.test (Id INT, EventTime DATETIME NULL, PosixTime INT NOT NULL) GO DECLARE @EventTime DATETIME = '20181001 12:00:00' DECLARE @GPSTime INT = DATEDIFF(SECOND, '19700101', @EventTime) INSERT INTO dbo.Test(Id, EventTime, PosixTime) VALUES (1, @EventTime, @GPSTime) , (2, NULL, @GPSTime) GO SELECT * FROM dbo.test GO ALTER TABLE dbo.test …

1
“警告:操作导致残留的I / O”与关键查找
我在SQL Server 2017执行计划中看到了以下警告: 警告:操作导致剩余IO [sic]。实际读取的行数为(3,321,318),但返回的行数为40。 这是SQLSentry PlanExplorer的片段: 为了改进代码,我添加了非聚集索引,因此SQL Server可以访问相关行。它工作正常,但通常索引中将包含太多(大)列。看起来像这样: 如果我仅添加索引,而没有包含列,则强制使用索引,如下所示: 显然,SQL Server认为密钥查找比剩余的I / O昂贵得多。我有一个没有大量测试数据的测试设置(但是),但是当代码投入生产时,它需要处理更多的数据,所以我很确定需要某种非聚集索引。 当您在SSD上运行时,关键查询真的那么昂贵吗?我必须创建全脂索引(包含很多包含列)吗? 执行计划: https : //www.brentozar.com/pastetheplan/?id=SJtiRte2X这是一个长存储过程的一部分。寻找IX_BatchNo_DeviceNo_CreatedUTC。

1
声明函数波动是否IMMUTABLE会损害性能?
Postgres函数用波动性分类VOLATILESTABLEIMMUTABLE声明,或。众所周知,该项目使用内置功能的这些标签非常严格。并且有充分的理由。一个突出的例子:表达式索引仅允许IMMUTABLE函数,并且它们必须是真正不变的,以避免错误的结果。 用户定义的函数仍然可以自由地声明,如所有者选择的那样。该手册建议: 为了获得最佳的优化结果,您应该使用对它们有效的最严格的波动性类别来标记您的函数。 ...并添加了错误的波动率标签可能会出错的大量问题列表。 尽管如此,在某些情况下伪造的不变性还是有意义的。通常,当您知道该函数在您的范围内实际上是不变的。例: PostgreSQL是否支持“不区分重音”的排序规则? 除了对数据完整性的所有可能影响,对性能有什么影响?人们可能会认为声明一个函数IMMUTABLE只会对性能有所帮助。是这样吗? 声明功能波动会IMMUTABLE 损害性能吗? 让我们假设当前的Postgres 10缩小了范围,但是所有最新版本都很有趣。

1
使用pg_trgm索引进行相似性搜索的查询时间慢
我们在表中添加了两个pg_trgm索引,以启用按电子邮件地址或名称的模糊搜索,因为我们需要按名称或注册过程中拼写错误的电子邮件地址(例如“ @ gmail.con”)查找用户。ANALYZE在创建索引后运行。 但是,在绝大多数情况下,对这两个索引中的任何一个进行排名搜索都非常缓慢。也就是说,随着超时的增加,查询可能会在60秒内返回,在极少数情况下可能会很快返回15秒,但通常查询会超时。 pg_trgm.similarity_threshold是的默认值0.3,但将其提高0.8似乎没有什么不同。 这个特定的表有超过2500万行,并且不断地对其进行查询,更新和插入(每个表的平均时间小于2ms)。设置为PostgreSQL 9.6.6,在具有通用SSD存储和或多或少默认参数的RDS db.m4.large实例上运行。pg_trgm扩展是1.3版。 查询: SELECT * FROM users WHERE email % 'chris@example.com' ORDER BY email <-> 'chris@example.com' LIMIT 10; SELECT * FROM users WHERE (first_name || ' ' || last_name) % 'chris orr' ORDER BY (first_name || ' ' || last_name) <-> 'chris orr' LIMIT …

1
在SQL Server 2017和Azure SQL DB中查找默认隔离级别
我正在读一本与交易和并发有关的书。在一个段落中提到: 在本地SQL Server实例中,默认隔离级别是基于锁定的已读提交 接下来的句子是: SQL数据库中的默认值为读取-基于行版本的已提交快照 我的问题是:这两个句子中的“本地SQL Server实例”和“ SQL数据库”之间有什么区别? 什么是默认隔离级别,如何找到它?是否有任何特殊查询来查找默认隔离级别?

1
为什么我的Azure SQL(SQL Server)数据库一次又一次出现数据IO超载?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为数据库管理员Stack Exchange 的主题。 6个月前关闭。 我正在S2版(50个DTU)下运行Azure SQL数据库。服务器的正常使用通常挂在10%左右的DTU上。但是,此服务器通常会进入一种状态,它将在数小时内将数据库的DTU使用率发送到85-90%。然后突然恢复到正常的10%使用率。 在此过载状态下,从应用程序对服务器进行的查询似乎仍在快速运行。 我可以从S2 =>任何东西(例如,S3)=> S2扩展服务器,似乎可以清除它挂起的任何状态。但是几个小时后,它将再次重复相同的重载状态周期。我注意到的另一个奇怪的事情是,如果我在S3计划(100 DTU)24/7上运行此服务器,则没有观察到此行为。当我将数据库缩减为S2计划(50 DTU)时,似乎只会发生这种情况。在S3计划中,我总是以5-10%的DTU使用率。显然未得到充分利用。 我已经检查了Azure SQL查询报告以查找流氓查询,但是我并没有发现任何异常,它显示了我所期望的使用资源的查询。 正如我们在这里看到的那样,用法全部来自数据IO。如果我更改此处的性能报告以按MAX显示热门的数据IO查询,我们将看到以下内容: 查看这些长期运行的需求似乎指向统计信息更新。从我的应用程序运行的内容实际上并不是什么。例如,查询16302显示: SELECT StatMan([SC0], [SC1], [SC2], [SB0000]) FROM (SELECT TOP 100 PERCENT [SC0], [SC1], [SC2], step_direction([SC0]) over (order by NULL) AS [SB0000] FROM (SELECT [UserId] AS [SC0], [OrganizationId] AS [SC1], [Id] AS [SC2] FROM …

2
是什么导致此查询/执行计划的CPU使用率过高?
我有一个支持.NET Core API应用程序的Azure SQL数据库。浏览Azure门户中的性能概述报告表明,我的数据库服务器上的大部分负载(DTU使用情况)来自CPU,特别是一个查询: 如我们所见,查询3780几乎负责服务器上的所有CPU使用率。 这有点说得通,因为查询3780(见下文)基本上是应用程序的整个关键所在,并且用户经常调用它。这也是一个相当复杂的查询,需要许多联接才能获得所需的正确数据集。该查询来自一个存储库,最终看起来像这样: -- @UserId UNIQUEIDENTIFIER SELECT C.[Id], C.[UserId], C.[OrganizationId], C.[Type], C.[Data], C.[Attachments], C.[CreationDate], C.[RevisionDate], CASE WHEN @UserId IS NULL OR C.[Favorites] IS NULL OR JSON_VALUE(C.[Favorites], CONCAT('$."', @UserId, '"')) IS NULL THEN 0 ELSE 1 END [Favorite], CASE WHEN @UserId IS NULL OR C.[Folders] IS NULL THEN …

2
为什么将group_concat_max_len设置为最大值以下?
Ubuntu 12.04上的MySQL 5.5.28 如果结果长于该时间,group_concat_max_len则结果将被优雅地截断。 当前,我有一个脚本,该脚本试图提前检查所需的长度并将其设置group_concat_max_len为足够大。 但是检查增加了额外的查询。设置group_concat_max_len为最大值有什么弊端?好处是更少的查询。


6
MySQL服务器上CPU系统时间占用率高
有点背景了,前段时间我们开始在我们的一个MySQL数据库上经历了很高的CPU系统时间。该数据库还受到磁盘利用率高的困扰,因此我们认为这些东西是连接的。由于我们已经计划将其迁移到SSD,因此我们认为它将解决这两个问题。 它有帮助...但是持续了很长时间。 迁移后的几周内,CPU图形如下: 但是现在我们回到了这一点: 这无处不在,没有在负载或应用程序逻辑上进行任何明显的更改。 数据库统计: MySQL版本-5.7.20 操作系统-Debian DB大小-1.2Tb 内存-700Gb CPU核心-56 窥探负载-大约5kq / s的读取,600q / s的写入(尽管选择查询通常非常复杂) 线程-50个正在运行,300个已连接 它有大约300个表,全部是InnoDB MySQL配置: [client] port = 3306 socket = /var/run/mysqld/mysqld.sock [mysqld_safe] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir …

1
Postgres:使用参数截断psql函数中是否存在
我试图获得一个psql函数,如果存在的话,它将截断给定的表名。我一直在尝试多种功能,但到目前为止它们都没有起作用。这是代码: CREATE OR REPLACE FUNCTION truncateIfExists(tableName TEXT) returns void as $$ BEGIN EXECUTE format( 'IF EXISTS ( SELECT * FROM information_schema.tables WHERE table_name =' || tableName || ' ) THEN TRUNCATE tableName; END IF; '); END; $$language plpgsql 现在,我可以使它在一个简单的过程中使用一个统一的名称工作: do $$ begin IF EXISTS (SELECT * FROM information_schema.tables WHERE table_name …

1
防止合并僵局
在我们的一个数据库中,我们有一个表,该表被多个线程密集并发访问。线程确实通过来更新或插入行MERGE。还有一些线程有时会删除行,因此表数据非常不稳定。进行upsert的线程有时会陷入死锁。该问题看起来类似于此问题中描述的问题。不过,不同之处在于,在我们的例子中,每个线程确实更新或插入一行。 简化的设置如下。该表是堆,上面有两个唯一的非聚集索引 CREATE TABLE [Cache] ( [UID] uniqueidentifier NOT NULL CONSTRAINT DF_Cache_UID DEFAULT (newid()), [ItemKey] varchar(200) NOT NULL, [FileName] nvarchar(255) NOT NULL, [Expires] datetime2(2) NOT NULL, CONSTRAINT [PK_Cache] PRIMARY KEY NONCLUSTERED ([UID]) ) GO CREATE UNIQUE INDEX IX_Cache ON [Cache] ([ItemKey]); GO 典型的查询是 DECLARE @itemKey varchar(200) = 'Item_0F3C43A6A6A14255B2EA977EA730EDF2', @fileName nvarchar(255) …

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.