数据库管理员

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

2
插入期间磁盘空间已满,会发生什么?
今天,我发现存储我的数据库的硬盘驱动器已满。这是以前发生的,通常原因很明显。通常会有一个错误的查询,这会导致大量的溢出到tempdb,直到磁盘装满为止。这次不太清楚发生了什么,因为tempdb不是驱动器满载的原因,而是数据库本身。 事实: 通常的数据库大小约为55 GB,后来增加到605 GB。 日志文件大小正常,数据文件很大。 数据文件具有85%的可用空间(我将其解释为“空气”:已使用但已释放的空间。SQLServer分配后将保留所有空间)。 Tempdb大小正常。 我发现了可能的原因;有一个查询选择了太多行的查询(错误的联接会导致选择110亿行,预计会有几十万行)。这是一个SELECT INTO查询,使我想知道是否可能发生以下情况: SELECT INTO执行 目标表已创建 数据被选择时插入 磁盘已满,导致插入失败 SELECT INTO被中止并回滚 回滚可以释放空间(已插入的数据将被删除),但是SQL Server不会释放释放的空间。 但是,在这种情况下,我不希望由创建的表SELECT INTO仍然存在,应该通过回滚将其删除。我测试了这个: BEGIN TRANSACTION SELECT T.x INTO TMP.test FROM (VALUES(1))T(x) ROLLBACK SELECT * FROM TMP.test 结果是: (1 row affected) Msg 208, Level 16, State 1, Line 8 Invalid object name 'TMP.test'. …

4
为什么varchar数据类型允许unicode值?
我有一个带有varchar列的表。允许使用商标(™),版权(©)和其他Unicode字符,如下所示。 Create table VarcharUnicodeCheck ( col1 varchar(100) ) insert into VarcharUnicodeCheck (col1) values ('MyCompany') insert into VarcharUnicodeCheck (col1) values ('MyCompany™') insert into VarcharUnicodeCheck (col1) values ('MyCompany░') insert into VarcharUnicodeCheck (col1) values ('MyCompanyï') insert into VarcharUnicodeCheck (col1) values ('MyCompany') select * from VarcharUnicodeCheck 但是varchar的定义说,它允许非Unicode字符串数据。但是Trademark(™)和Registered(®)符号是Unicode字符。该定义是否与varchar数据类型的属性相矛盾?我读了几个链接,例如第一个和第二个。但是,当定义说它仅允许非Unicode字符串值时,我仍然不明白为什么它允许Unicode字符串。

1
忽略“哪里”的口音
在我们的数据库中,我们有关于caron / hatschek的多个条目。现在,当我们的用户搜索不带caron / hatschek的条目时,他们希望找到这些条目。我将通过一个简单的示例来说明这一点: 在我们的数据库中,我们有条目(带有姓名的联系方式) Millière 所以这个名字在这个人居住的国家是正确的。 在我们的国家/地区,caron / hatschek没有任何字符,因此我们的用户搜索Milliere。没有结果,è显然不匹配e。 我不知道这到底是怎么实现的é,è,ê还有更多可供选择(而这仅是字母一个例子e......)。 (另一种方法会容易得多,因为我可以简单地将所有字母替换为用caron / hatschek替换为基本字母。显然,我们的用户确实希望数据库中使用正确的名称版本,而不是残缺的名称。)

2
Postgres侦听/通知为消息队列
有什么方法可以使用Postgres侦听/通知功能将消息传递到通道,并且只有一个侦听器使用此消息吗? 这样做的目的是让我有多个“工作者”应用程序都在收听同一个Postgres频道。但是我只希望每个通过通知渠道收到的消息都完成一次工作。 如果“听/通知”不是Postgres中的正确功能,是否应该使用其他功能? 理想情况下,我希望不使用任何其他扩展名即可执行此操作。

2
更新所有列(即使是未更改的列)的开销是多少?
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 2年前关闭。 在更新行时,许多ORM工具都会发出UPDATE语句来设置与该特定实体相关联的每一列。 优点是您可以轻松批处理update语句,因为UPDATE无论您更改什么实体属性,该语句都是相同的。此外,您甚至还可以使用服务器端和客户端语句缓存。 因此,如果我加载一个实体并仅设置一个属性: Post post = entityManager.find(Post.class, 1L); post.setScore(12); 所有列都将被更改: UPDATE post SET score = 12, title = 'High-Performance Java Persistence' WHERE id = 1 现在,假设我们在title属性上也有一个索引,DB难道不应该意识到该值没有改变吗? 在本文中,Markus Winand说: 所有列上的更新都显示了我们在上一节中已经观察到的相同模式:响应时间随每个其他索引的增加而增加。 我不知道为什么会产生这种开销,因为数据库将相关的数据页从磁盘加载到内存中,从而可以确定是否需要更改列值。 即使对于索引,它也不会重新平衡任何内容,因为对于未更改的列,索引值不会更改,但是它们已包含在UPDATE中。 是否也需要导航与冗余未更改列关联的B +树索引,只是为了让数据库意识到叶值仍然相同? 当然,某些ORM工具允许您仅更新已更改的属性: UPDATE post SET score = 12, WHERE id = 1 但是,当为不同的行更改不同的属性时,这种类型的UPDATE可能并不总是从批量更新或语句缓存中受益。

3
SQL Server中的分页
我有一个非常大的数据库,大约100 GB。我正在执行查询: select * from <table_name>; 我只想显示第100至200行。 我想了解内部情况。数据库是否将所有记录从磁盘中提取到内存中,然后将第100至400行发送回查询客户端?还是存在任何机制,以便仅使用B树等索引机制从数据库中提取那些记录(第100个-200个)? 我发现这与分页概念有关,但是我无法确切找到它在数据库级别内部如何发生。

4
SQL Server 2016 DB邮件未发送
我正在使用SQL Server 2016,并受到冲击...我的DB Mail无法发送,而且我的地方用光了。我仔细检查了对DBmail可执行文件的SQL帐户权限-它已读取并执行。我输入了防火墙出站端口587的规则。我尝试了另一个具有相同未发送问题的邮件帐户和配置文件。日志(db邮件日志)中唯一的条目是服务的开始和结束。我在任何地方都找不到错误。电子邮件似乎只是进入发送队列,而永不离开。这些帐户可以自己发送邮件,也可以从另一台计算机上的SQL Server 2014实例接收电子邮件。 我有一排发送状态为“未发送”的项目,除了一长列未发送的邮件之外,还检查了所有正常位置的所有预期结果: SELECT * FROM msdb..sysmail_event_log order by log_id DESC SELECT * FROM dbo.sysmail_mailitems SELECT * FROM dbo.sysmail_sentitems USE msdb SELECT sent_status, * FROM sysmail_allitems SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb'; EXECUTE msdb.dbo.sysmail_help_status_sp 我尝试将其关闭然后再打开...所以我错过了DMV等可能会发现这种情况的信息吗?这是我在搜索中没有发现的SQL Server 2016的已知问题吗?还有其他可能的步骤来发送此邮件吗?



1
编写SQL查询的最佳方法,该方法检查列中是否为非NULL值或NULL
我有一个带有默认值为NULL的参数的SP,然后我想执行以下查询: SELECT ... FROM ... WHERE a.Blah = @Blah AND (a.VersionId = @VersionId OR (@VersionId IS NULL AND a.VersionId IS NULL)); 在WHERE上述检查两个非空值和一个NULL值@VersionId。 就性能而言,最好改用一条IF语句并将查询复制到一个搜索非NULL的查询中,而将另一个复制为NULL的查询,这样会更好吗?: IF @VersionId IS NULL BEGIN SELECT ... FROM ... WHERE a.Blah = @Blah AND a.VersionId IS NULL; ELSE BEGIN SELECT ... FROM ... WHERE a.Blah = @Blah …

2
SQL Server UniqueIdentifier / GUID内部表示
我的一个同事给我发了一个有趣的问题,我无法完全解释。 他运行了一些代码(包括在下面),并从中获得了一些意外的结果。 本质上,将UniqueIdentifier(从现在开始,我将其称为)类型Guid转换为binary(或varbinary)类型时,结果的前半部分的顺序是向后的,但后半部分的顺序不是。 我的第一个想法是,系统的字节序是原因,并且Guid保留了显示,但是binary不能保证形式。 显然,这是一个实现细节,但是我想知道是否对此有一个很好的解释。 码: declare @guid uniqueidentifier = '8A737954-CBEC-40CE-A534-2AFFB5A0E207'; declare @binary binary(16) = (select convert(binary(16), @guid)); select @guid as [GUID], @binary as [Binary]; 结果: GUID Binary 8A737954-CBEC-40CE-A534-2AFFB5A0E207 0x5479738AECCBCE40A5342AFFB5A0E207 如您所见,Guid(一直到40CE)的前半部分对于每个部分都向后存储。也就是说,的第一部分Guid向后,然后是第二部分,然后是第三部分,但是保留了这些部分的顺序。之后,最后两节将按照它们在中显示的确切顺序进行存储Guid。 谁能解释一下?(下面包括一个更大的测试集。) 码: declare @guid_to_binary table ( [id] int identity(1,1), [guid] uniqueidentifier, [binary_conversion] binary(16) ); declare @i int = 1; …


1
使用SQL Server 2016系统版本的时态表进行慢速变化维度的查询策略
当使用系统版本的时态表(SQL Server 2016中的新增功能)时,当此功能用于处理大型关系数据仓库中的维缓慢变化时,查询创作和性能含义是什么? 例如,假设我有一个Customer带有Postal Code列的100,000行维,一个Sales带有CustomerID外键列的数十亿行事实表。并假设我要查询“按客户的邮政编码进行的2014年销售总额”。简化的DDL就是这样(为了清楚起见,省略了许多列): CREATE TABLE Customer ( CustomerID int identity (1,1) NOT NULL PRIMARY KEY CLUSTERED, PostalCode varchar(50) NOT NULL, SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL, SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL, PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime) ) WITH (SYSTEM_VERSIONING = ON); …

1
什么限制了连接数量?
根据https://devcenter.heroku.com/articles/heroku-postgres-legacy-plans,连接限制为500 按照https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server的说法: “通常,良好硬件上的PostgreSQL可以支持数百个连接” 此限制的决定因素是什么?#CPU核心?内存?操作系统?

1
为什么不重建页数小于1000的索引?
我使用Ola Hallengrens脚本进行索引维护。在此之前,我使用以下查询来查看哪些索引最分散: SELECT dbschemas.[name] as 'Schema', dbtables.[name] as 'Table', dbindexes.[name] as 'Index', indexstats.avg_fragmentation_in_percent, indexstats.page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id] INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id] INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id] AND indexstats.index_id …

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.