当我执行SHOW PARAMETER CONTROL_MANAGEMENT_PACK_ACCESS
时,它给了我这个 Oracle 参数的值,作为看起来是包含三列(名称、类型和值)的单行的一部分。如何将此值放入以后可以在脚本中使用的变量或表中?
我试图稍后在我的脚本中根据一些参数值做出决定,但我不确定如何将它们存储在持久的东西中。
当我执行SHOW PARAMETER CONTROL_MANAGEMENT_PACK_ACCESS
时,它给了我这个 Oracle 参数的值,作为看起来是包含三列(名称、类型和值)的单行的一部分。如何将此值放入以后可以在脚本中使用的变量或表中?
我试图稍后在我的脚本中根据一些参数值做出决定,但我不确定如何将它们存储在持久的东西中。
我们的网络上有一些应用程序(在我之前),它们在其 SQL Server 连接字符串中使用 SA 帐户。它在源代码中是硬编码的,无论出于何种原因,我们都无法更改它——我的问题不是关于我们为什么要更改它,而是关于如何解决它。
我正在考虑将 SA 帐户重命名为其他名称(例如“SysAccount”或类似名称,并为其提供新密码),然后使用旧密码创建一个名为“SA”的新帐户并授予其适合应用程序的权限(显然不是系统管理员角色的成员)。这样做有什么陷阱吗?如果名为 SA 的帐户实际上不是系统管理员,SQL Server 是否会遇到已知问题?
我假设由于我只是重命名帐户,所以我很安全 - 它的 uid 仍然为 0x01,我已经对此进行了测试,它在物理上是可行的,并且在测试中似乎可以正常工作,但我想确保我不会忽视任何明显会因此而崩溃的东西。如果它破坏了东西,我总是可以删除新的 SA 并重命名旧的 SA 以消除损坏,但希望避免尝试和失败。
我正在使用 SQL Server 2012,但我怀疑相同的答案将适用于任何现代版本。我已经看到如果你这样做了,从 2005 到 2008 的升级可能会中断的错误,但我想这早就解决了。
据我了解,SQL Server(或任何其他 RDBMS,实际上)中的查询优化器并不知道数据库下存储的性能,并且会做出决策,就好像所有存储都具有相同的成本一样。那是准确的,还是考虑了一些存储性能的知识?
在一个完全人为的例子中,假设我的表行存储在我的 SAN 中的 SSD 驱动器上,具有瞬时访问时间,而我的索引存储在 SAS 驱动器上,这些驱动器极度过载,导致磁盘饱和和常量磁盘队列。当 RDBMS 生成执行计划时,它是否更倾向于表扫描而不是索引操作(或者可能是瘦索引和相关表查找,而不是覆盖索引,因为它在 SAS 磁盘上的 IO 更少)?
我怀疑答案是肯定的“优化器不可能那么聪明甚至知道磁盘性能”,但我只是想看看是否有人确定知道。我正在使用 SQL Server,但我对任何数据库系统都感兴趣。
由于我是一名 DBA(在许多情况下是事实上的系统管理员),SQL Server 几乎安装在我必须经常使用的每台服务器上。我最近意识到,我几乎在所有情况下都使用 SQL 代理作为作业调度程序,而不是原生的 Windows 任务调度程序。
从我的角度来看,SQL 代理比原生 Windows 任务计划程序有很多优势:
但是,我无法摆脱这种不好的做法的感觉——SQL 代理应该只保留用于与数据库相关的任务,并且我应该让操作系统级别的任务在 Windows 任务计划程序中运行,尽管我不喜欢它的可用性。
以这种方式依赖 SQL Agent 可以吗?如果没有,我是否应该考虑使用第三方 Windows 任务计划程序来获得我正在寻找的某些功能?
我有一个带有“TOP (X)”子句的 SQL UPDATE 语句,我正在更新值的行有大约 40 亿行。当我使用“TOP (10)”时,我得到一个几乎立即执行的执行计划,但是当我使用“TOP (50)”或更大时,查询永远不会(至少在我等待时不会)完成,并且它使用完全不同的执行计划。较小的查询使用一个非常简单的计划,其中包含一对索引查找和一个嵌套循环连接,其中完全相同的查询(在 UPDATE 语句的 TOP 子句中具有不同的行数)使用一个涉及两个不同索引查找的计划、表假脱机、并行性和一堆其他复杂性。
我使用“OPTION (USE PLAN...)”来强制它使用由较小查询生成的执行计划——当我这样做时,我可以在几秒钟内更新多达 100,000 行。我知道查询计划很好,但是 SQL Server 只会在只涉及少量行时自行选择该计划 - 我的更新中任何相当大的行数都会导致次优计划。
我认为并行性可能是罪魁祸首,所以我设置MAXDOP 1
了查询,但没有效果 - 这一步已经消失,但糟糕的选择/性能没有。我今天早上也跑sp_updatestats
了,以确保这不是原因。
我附上了两个执行计划——越短的也越快。此外,这是有问题的查询(值得注意的是,我包含的 SELECT 在小行数和大行数的情况下似乎都很快):
update top (10000) FactSubscriberUsage3
set AccountID = sma.CustomerID
--select top 50 f.AccountID, sma.CustomerID
from FactSubscriberUsage3 f
join dimTime t
on f.TimeID = t.TimeID
join #mac sma
on f.macid = sma.macid
and t.TimeValue between sma.StartDate and sma.enddate
where f.AccountID = 0 --There's a filtered index on the table for this
在我设置查询的方式或在提供的执行计划中是否有任何明显的东西会导致查询引擎做出错误的选择?如有必要,我还可以包括所涉及的表定义和在它们上定义的索引。
对于那些要求仅统计版本的数据库对象的人: 我什至没有意识到您可以做到这一点,但它完全有道理!我尝试为仅统计数据库生成脚本,以便其他人可以自己测试执行计划,但我可以在我的过滤索引上生成生成统计/直方图(脚本中似乎存在语法错误),所以我运气不好。我尝试删除过滤器,查询计划很接近,但不完全相同,我不想让任何人去追逐。
更新和一些更完整的执行计划: 首先,SQL Sentry 的计划资源管理器是一个令人难以置信的工具。在查看此站点上的其他查询计划问题之前,我什至不知道它的存在,并且它对我的查询如何执行有很多话要说。虽然我不确定如何解决这个问题,但他们清楚地表明了问题所在。
这是 10、100 和 1000 行的摘要 - 您可以看到 1000 行查询与其他查询不符:
你可以看到第三个查询有一个荒谬的读取次数,所以它显然做了一些完全不同的事情。这是估计的执行计划,带有行数。 1000行预估执行计划:
这是执行计划的实际结果(顺便说一句,“永远不会完成”,原来我的意思是“在一小时内完成”)。 1000行实际执行计划
我注意到的第一件事是,它并没有像预期的那样从 dimTime 表中提取 60K 行,而是实际提取了 16 亿行,并带有 B。查看我的查询,我不确定它是如何从 dimTime 表中拉回这么多行的。我使用的 BETWEEN 运算符只是确保我根据 Fact 表中的时间记录从#mac 中提取正确的记录。但是,当我在 WHERE 子句中添加一行时,我将 t.TimeValue(或 t.TimeID)过滤为单个值,我可以在几秒钟内成功更新 100,000 行。因此,正如我在执行计划中所明确指出的那样,很明显问题出在我的时间表上,但我不确定如何更改连接标准以解决此问题并保持准确性. 有什么想法吗?
作为参考,这里是 100 行更新的计划(带有行数)。您可以看到它达到了相同的索引,并且仍然有大量的行,但远没有达到相同程度的问题。 具有行数的 100 行执行: