数据库管理员

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

2
允许用户在自己的架构中执行任何操作,但不能创建或删除架构本身
我已经在SQL Azure中创建了一个架构,并授予了数据库角色以下权限: CREATE ROLE myrole AUTHORIZATION dbo; EXEC sp_addrolemember 'myrole', 'myuser'; CREATE SCHEMA myschema AUTHORIZATION dbo; GRANT ALTER, CONTROL, DELETE, EXECUTE, INSERT, REFERENCES, SELECT, UPDATE, VIEW DEFINITION ON SCHEMA::myschema TO myrole; GRANT CREATE TABLE, CREATE PROCEDURE, CREATE FUNCTION, CREATE VIEW TO myrole; 通过上面定义的权限myuser可以创建/删除他自己的架构,因此为了解决该问题,我尝试了ALTER ANY SCHEMA权限。但是此权限也拒绝用户创建/删除表。 为了允许用户在自己的架构中执行任何操作但不能创建或删除架构本身,需要什么权限?

1
为什么DELETE比SELECT慢得多,然后按ID进行DELETE?
我有一个非常繁忙的InnoDB表(200,000行,我猜每秒大概有几十个查询)。由于一个错误,我得到了14行,其中包含(相同)无效的电子邮件地址,并希望将其删除。 我只是尝试DELETE FROM table WHERE email='invalid address'了一下,并在大约50秒后得到了“超出了锁定等待超时”。这并不奇怪,因为未对行列进行索引。 但是,然后我做了SELECT id FROM table WHERE email='invalid address',那花了1.25秒。运行DELETE FROM table WHERE id in (...),从SELECT结果中复制粘贴ID,花费了0.02秒。 到底是怎么回事?有人可以解释为什么带有条件的DELETE这么慢以至于超时,但是执行SELECT然后按ID删除却是如此之快吗? 谢谢。 编辑:根据要求,我发布了表结构以及一些explain结果。我还应注意,没有任何外键引用此表。 但是,这种情况对我来说似乎很简单:我有一个未索引的字段可供选择。这需要扫描整个表,但是它并不大。id是主键,因此按ID删除应该是非常快速的。 mysql> show create table ThreadNotification2 \G *************************** 1. row *************************** Table: ThreadNotification2 Create Table: CREATE TABLE `ThreadNotification2` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `alertId` bigint(20) DEFAULT …

3
使用带覆盖列的唯一非聚集索引而不是主键的含义
我们有一个大表[MyTable]目前既有Primary Key,和一个Unique Non Clustered Index在同一列([KeyColumn])。U NC索引还具有其他覆盖列。 在同一列上同时拥有PK和唯一NC索引似乎是多余的,因此我考虑删除主键,而是出于引用完整性的目的而使用唯一非聚集索引。 请注意,该表完全由另一列群集。 即所以我们有: ALTER TABLE [MyTable] ADD CONSTRAINT [PK_MyTable] PRIMARY KEY NONCLUSTERED ([KeyColumn]) GO 和 CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable_SomeIndex] ON [MyTable] ([KeyColumn]) INCLUDE ([Column1], [Column2]) GO 据我所知,不可能将覆盖列添加到主键,所以我打算这样做: 放弃依赖于的外键约束 MyTable.KeyColumn 将主键MyTable.KeyColumn完全放在 将外键重新添加到表中(即RI将通过强制执行MyTable.KeyColumn) 我能想到的唯一含义是,我们不会在ERD图上看到可视键符号,并且由于包含了列,因此(叶)索引密度会降低。 我已阅读/programming/487314/primary-key-or-unique-index,并对这样做的完整性和性能方面感到满意。 我的问题是:这种方法有缺陷吗? 编辑 我要完成的任务:性能优化和春季大扫除。通过删除PK或索引,我的索引所需的页面将更少=更快的写入速度,再加上维护/操作的好处,即减少索引以保持碎片整理等。 为了提供一些背景知识,我从来没有过没有PK的表被引用过。但是,在表中添加了带有覆盖列的NC索引这一事实意味着我需要调整自己的想法。



4
处理CXPACKET等待-设置并行性的成本阈值
作为我先前对Sharepoint网站进行性能故障的先前问题的补充,我想知道我是否可以对CXPACKET等待做点什么。 我知道下意识的解决方案是通过将MAXD​​OP设置为1来关闭所有并行性-听起来是个坏主意。但是另一个想法是在并行开始之前增加成本阈值。执行计划成本的默认值5相当低。 因此,我想知道是否存在已经写好的查询,该查询将为我找到执行计划成本最高的查询(我知道您可以找到执行时间最长的查询,依此类推-但是执行计划成本是否可在某处检索到,也可以),这还会告诉我是否已经并行执行了这样的查询。 是否有人手头有这样的脚本,或者可以将我指向相关DMV,DMF或其他系统目录视图的方向,以找出答案?

3
PostgreSQL初始数据库大小
我的问题分为两部分。 有没有一种方法可以在PostgreSQL中指定数据库的初始大小? 如果没有,当数据库随着时间增长时如何处理碎片? 我最近从MSSQL迁移到Postgres,在创建数据库时我们在MSSQL世界中所做的一件事是指定数据库和事务日志的初始大小。这样可以减少碎片并提高性能,尤其是如果事先知道数据库的“正常”大小时。 数据库的性能随着大小的增长而下降。例如,我要处理的工作量通常需要10分钟。随着数据库的增长,这个时间增加了。进行VACUUM,VACUUM FULL和VACUUM FULL ANALYZE似乎无法解决问题。解决性能问题的方法是停止数据库,对驱动器进行碎片整理,然后进行VACUUM FULL ANALYZE,将测试的性能恢复到最初的10分钟。这使我怀疑碎片化是导致我疼痛的原因。 我在Postgres中找不到任何有关保留表空间/数据库空间的引用。我使用的术语错误,因此一无所获,或者在Postgres中有另一种缓解文件系统碎片的方法。 有指针吗? 解决方案 提供的答案有助于确认我开始怀疑的地方。PostgreSQL将数据库存储在多个文件中,这使数据库可以增长而无需担心碎片。默认行为是将这些文件与表数据一起打包到边缘,这对很少更改的表有好处,但对经常更新的表不利。 PostgreSQL利用MVCC提供对表数据的并发访问。在此方案下,每次更新都会创建已更新行的新版本(可以通过时间戳或版本号,谁知道呢?)。旧数据不会立即删除,但会标记为删除。实际删除发生在执行VACUUM操作时。 这与填充因子有何关系?表格默认填充因子100完全填满了表格页面,这又意味着表格页面中没有空间来容纳更新的行,即,更新的行将与原始行放置在不同的表格页面中。如我的经验所示,这对性能不利。由于汇总表的更新非常频繁(最高1500行/秒),因此我选择将填充因子设置为20,即表的20%用于插入的行数据,而80%用于更新数据。尽管这看起来可能过多,但为更新的行保留的大量空间意味着更新的行与原始行位于同一页面内,并且在自动清理守护程序运行以删除过时的行时,表页面未满。 为了“修复”我的数据库,我做了以下工作。 将摘要表的填充因子设置为20。您可以在创建时通过将参数传递给CREATE TABLE或在事后通过ALTER TABLE来实现。我发出了以下plpgsql命令:ALTER TABLE "my_summary_table" SET (fillfactor = 20); 发出VACUUM FULL,因为这将写入表文件的全新版本,因此,暗含了使用新的填充因子写入新的表文件的情况。 重新运行测试,即使数据库足够大以容纳数百万行,我也看不到性能下降。 TL; DR-不是文件碎片造成的,而是表空间碎片造成的。通过调整表格的填充因子以适合您的特定用例,可以缓解这种情况。

3
为什么我的ORDER BY在EXCEPT(慢)之前而不是在(快)之后对两个表排序?
SQL Server 2008 R2查询优化器难题 我们有两个表,每个表都包含900万行。70.000行不同,其他相同。 快13秒 select * from bigtable1 except select * from similar_bigtable2 这样可以对输出进行排序,而且速度也很快(13秒), select * into #q from bigtable1 except select * from similar_bigtable2 select * from #q order by sort_column 尽管这非常慢: ;with q as ( select * from bigtable1 except select * from similar_bigtable2 ) select …

2
删除数据库后释放磁盘空间
我正在开发一个dev系统,并且一直在还原到我用于开发目的的数据库“ foo”。在处理这些问题时,我刚刚运行了DROP DATABASE foo。但是,我很快意识到我已经吃光了磁盘上的所有空间。废话 VACUUM FULL是否从另一个逻辑数据库中释放了我先前删除的数据库(foo)的空间?我从另一个逻辑数据库中尝试了此操作,并回收了可用空间,但我认为这不足以解决我进行的所有CREATE DATABASE / DROP DATABASE调用。它可能只是对我运行的逻辑数据库进行了真空处理。 必须有一种无需执行整个数据库初始化就可以回收该空间的方法吗? 编辑 因此,我大致按照以下步骤从备份重新初始化了数据库。还原后,我已经收回了磁盘上的大量空间!现在可以使用,但是有关如何清除删除的数据库的任何帮助仍然有用。 编辑2 因此,我设法收集了有关此问题的更多信息...这是我想出的一个示例: Initial partition size: Size Used Avail Use% Mounted on 25G 8.1G 16G 35% /apps1 After creating my new database and populating it: 25G 18G 6.4G 73% /apps1 After Dropping the database using "DROP database mydb" …

1
在JDBC中禁用显式提交,在SQL中检测它们,或将数据库置于只读状态
背景:我正在http://sqlfiddle.com(我的网站)上工作,并试图防止可能的一种滥用途径。我希望通过询问我当前要解决的问题,我不会无意间使潜在的虐待更为严重,但是您能做什么?我相信你们。 我想防止任何用户在给定的交易块内发出明确的“提交”调用。从SQL Fiddle的上下文来看,事务块是在右侧面板上执行的代码。基本上,我遍历并执行一系列明文SQL命令,并且我想确保它们所做的所有更改都将在批处理结束时回滚。通常,它们的更改会回滚,但是有时文本中会包含明确的“ commit”语句,因此我的回滚当然是行不通的。用户试图破坏SQL Fiddle上的架构时,很可能发生这种显式提交,因此其他从事此操作的人将看到错误。 主要期望结果:如果可能,我想在JDBC级别禁用显式提交。这是因为我必须支持多个数据库后端供应商,并且当然每个供应商都有其低级的怪癖。 Fallback选项:如果无法将JDBC配置为禁用显式提交,那么我将接受在处理以下每个后端批处理时检测显式提交的解决方案:SQL Server,Oracle,MySQL和PostgreSQL。 对于SQL Server,我想到了这种解决方案:在执行该语句之前,先解析XML查询计划中的语句,然后检查是否存在与该XPath相匹配的条目: //*[@StatementType="COMMIT TRANSACTION"] 我认为这对于SQL Server来说会很好。但是,这种方法不适用于其他数据库类型。Oracle针对显式提交的XML执行计划输出未引用您正在运行commit语句的事实(而只是重复从其提交的查询中重复执行计划输出)。PostgreSQL和MySQL根本不为显式提交提供任何执行计划输出(XML或其他方式)。 剩下的工作就是检查“ commit”一词的实际陈述。这将起作用,除非可能存在各种变化: declare @sql varchar(50) set @sql = 'com' + 'mit' exec(@sql); 上面是SQL Server的示例(我可以解决),但是我想Oracle,MySQL和PostgreSQL可能会发生类似的事情。我在这个假设上错了吗?也许他们不允许“动态”提交语句?随意使用SQL Fiddle(最好不要使用示例架构或可能正在使用的其他示例)来查看是否可以在Oracle,MySQL和PostgreSQL中进行类似的操作。如果没有,也许简单的字符串检测可能适用于那些。 还有另一种可能性 我想到了另一个选择-如果您知道一种将这些数据库中的任何一个设置为只读模式的方法,例如在该模式下,什么也不能提交,那也可以工作。只要在该模式下什么也不能提交,我就仍然需要允许启动事务并在其中运行代码。那可能吗? 更新资料 我最近学到的-PostgreSQL实际上不是问题。显然,如果同一交易块最终被回滚(在Postgres中),则该交易块中发出的提交将不适用。所以为Postgres致敬! 多亏了Phil在SO帖子上的链接,我想我可以使用DEFERRABLE INITIALIALLY DEFERRED hack for Oracle来完成我要执行的操作(如果发出了提交,将会引发错误,但是我可以解决这个问题)。这应该针对Oracle。(我想了一会儿嵌套事务可能在这里工作,但是Oracle似乎不支持嵌套事务?无论如何,我找不到以这种方式工作的任何东西)。 真的还没有针对MySQL的解决方案。使用嵌套事务进行了尝试,但这似乎不起作用。我正在认真考虑MySQL的更严格的方法,例如不允许在右侧使用SELECT或在每次查询后删除/重新创建数据库。听起来都不好。 解析度 因此,我现在已经为SQL Server和Oracle实现了所描述的解决方案,并且正如我提到的那样,对于PostgreSQL来说这实际上不是问题。对于MySQL,我采取了一些不幸的步骤,将查询面板限制为仅选择语句。仅需在架构面板(左侧)上输入用于MySQL的DDL和DML。我希望这不会破坏太多的旧提琴,但是我认为这只是确保数据一致性所要做的。谢谢!



2
对多个查询列使用相同的CASE WHEN条件
是否存在一种“更好”的方式来重写SELECT子句,其中多个列使用相同的CASE WHEN条件,以便仅检查条件一次? 请参见下面的示例。 SELECT CASE testStatus WHEN 'A' THEN 'Authorized' WHEN 'C' THEN 'Completed' WHEN 'P' THEN 'In Progress' WHEN 'X' THEN 'Cancelled' END AS Status, CASE testStatus WHEN 'A' THEN authTime WHEN 'C' THEN cmplTime WHEN 'P' THEN strtTime WHEN 'X' THEN cancTime END AS lastEventTime, CASE testStatus WHEN …

4
是否可以在不使用Integration Services的情况下导出维护计划?
我正在尝试从SQL Server实例导出简单的维护计划。 我想检查导出到源代码管理中,并将导出的维护计划应用于功能相同的实例。 StackOverflow和SQL Server新手建议使用Integration Services导出维护计划。 当我尝试连接到导出目标上的Integration Services时,出现以下错误: 连接到“ WEBSERVER”计算机上的Integration Services服务失败,出现以下错误:指定的服务不存在为已安装的服务。 我们选择在WEBSERVER上禁用Integration Services,因为我们仅使用此框将数据提供给使用者应用程序。WEBSERVER上的所有数据都是从后端实例复制的。Integration Services被大量用于处理后端实例上的数据。 有没有书面记录的方式可以在不使用Integration Services的情况下导出维护计划?微软支持吗?

2
位与布尔列
假定位字段只是数据的二进制表示形式,则需要以稍微“奇怪”的方式进行查询。 使用位字段作为布尔值实际上有什么好处吗?从我看来,这似乎表明空间是唯一的真正好处。

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.