检查昨天的生产日志,我们发现在大约 5 分钟的时间里,一大堆非常简单的查询超时。对服务器日志的进一步调查显示磁盘活动出现了巨大的峰值,这使我得出结论,当时正在数据库上运行自动 CHECKPOINT。
这是我真的不想在高峰时段发生的事情。所以我想在非高峰时间每天安排一个每日检查点。
这是一个好主意吗?馊主意?浪费时间?如果不是这样,那又如何?
检查昨天的生产日志,我们发现在大约 5 分钟的时间里,一大堆非常简单的查询超时。对服务器日志的进一步调查显示磁盘活动出现了巨大的峰值,这使我得出结论,当时正在数据库上运行自动 CHECKPOINT。
这是我真的不想在高峰时段发生的事情。所以我想在非高峰时间每天安排一个每日检查点。
这是一个好主意吗?馊主意?浪费时间?如果不是这样,那又如何?
我有一个用户ls_readonly
应该db_datareader
对多个数据库具有特权。我以为我设置正确:
但是当我连接到服务器ls_readonly
并尝试在对象资源管理器中打开数据库时,出现错误:
数据库 wtest 不可访问。(对象浏览器)
我打开一个查询窗口master
并尝试运行:
use wtest
这回应:
Msg 916, Level 14, State 1, Line 1
The server principal "ls_readonly" is not able to access the database "wtest" under the current security context.
我错过了什么?
更新:这是一个线索。ls_readonly
如果我作为用户从数据库的安全上下文中删除,那么我会转到服务器安全上下文下的用户并在“用户映射”下授予对数据库的访问权限,然后它开始工作。
可能是该数据库最初是从另一台服务器恢复的,该服务器也有一个ls_readonly
用户。我猜那用户标识不是基于用户名?
我正在建立一个 SaaS 系统,我们计划为每个客户提供自己的数据库。该系统已经设置好,因此如果负载变得太大,我们可以轻松地扩展到其他服务器;我们希望有成千上万的客户,甚至数以万计的客户。
当我说“微型数据库”时,我并不是指“微型”;我的意思是我们的目标是成千上万的客户,所以每个单独的数据库只占总数据存储的千分之一或更少。实际上,每个数据库都在 100MB 左右,具体取决于它的使用量。
使用 10,000 个数据库的主要原因是为了可扩展性。事实上,V1 系统有一个数据库,当数据库在负载下紧张时,我们有过一些不舒服的时刻。
它使 CPU、内存、I/O 紧张——以上所有。尽管我们解决了这些问题,但它们让我们意识到,在某些时候,即使拥有世界上最好的索引,如果我们像我们希望的那样成功,我们根本无法将所有数据放在一个大本营' 数据库。所以对于 V2,我们正在分片,所以我们可以在多个数据库服务器之间分配负载。
去年我一直在开发这个分片解决方案。它是每台服务器一个许可证,但无论如何,由于我们在 Azure 上使用虚拟机,因此已经处理好了。现在出现这个问题的原因是因为以前我们只向大型机构提供服务并自己设置每个机构。我们的下一个业务订单是自助服务模式,任何拥有浏览器的人都可以注册并创建自己的数据库。他们的数据库将比大型机构小得多,数量也多得多。
我们尝试了 Azure SQL 数据库弹性池。性能非常令人失望,因此我们切换回常规 VM。
(与这个问题有关)
如果我想查看当前是否在我的数据库上执行任何长时间运行的查询,最简单的检查方法是什么?(我希望答案会是一些关于master..sysprocesses
?)
我经常发现,当我的 MSSQL 数据库出现性能问题时,我可以通过运行sp_UpdateStats
. 我了解到这一点是因为这始终是技术支持的第一道防线,紧随其后的是“您的计算机打开了吗?”
我的理解是 SQL Server 应该自动保存统计信息;我不应该需要保姆它。所以我想了解:什么情况下可能会导致统计数据严重过时以至于我需要手动更新它们?
我有一个用户定义的功能:
create function ut_FooFunc(@fooID bigint, @anotherParam tinyint)
returns @tbl Table (Field1 int, Field2 varchar(100))
as
begin
-- blah blah
end
现在我想在另一张桌子上加入这个,像这样:
select f.ID, f.Desc, u.Field1, u.Field2
from Foo f
join ut_FooFunc(f.ID, 1) u -- doesn't work
where f.SomeCriterion = 1
换句话说,对于所有为 1 的Foo
记录SomeCriterion
,我想查看Foo
ID
和Desc
,以及为 的输入返回的Field1
和的值。Field2
ut_FooFunc
Foo.ID
这样做的语法是什么?
我有一个存储过程:
create proc sp_MyProc(@calcType tinyint) as
begin
-- some stuff collating data into #MyTempTable
if (@calcType = 1) -- sum
select A, B, C, CalcField = sum(Amount)
from #MyTempTable t
join AnotherTable a on t.Field1 = a.Field1;
group by A, B, C
else if (@calcType = 2) -- average
select A, B, C, CalcField = avg(Amount)
from #MyTempTable t
join AnotherTable a on t.Field1 = a.Field1;
group by A, B, C
else if (@calcType = 3) -- some other fancy formula
select A, B, C, CalcField = sum(case when t.Type = 1 then 1 else 0 end) * t.Factor
from #MyTempTable t
join AnotherTable a on t.Field1 = a.Field1;
group by A, B, C
-- plus a whole bunch of other, similar cases
else
select A, B, C, CalcField = 0.0
from #MyTempTable t
join AnotherTable a on t.Field1 = a.Field1;
group by A, B, C
end
现在,@calcType 的不同值的所有这些不同情况似乎都在浪费大量空间并导致我到处复制和粘贴,这总是让我脊背发凉。
是否有某种方法可以为 CalcField 声明一个函数,类似于 C# 中的 lambda 表示法,以使我的代码更加紧凑和可维护?我想做这样的事情:
declare @func FUNCTION(@t #MyTempTable) as real -- i.e. input is of type #MyTempTable and output is of type real
if (@calcType = 1) -- sum
set @func = sum(@t.Amount)
else if (@calcType = 2) -- average
set @func = avg(@t.Amount)
else if (@calcType = 3) -- some other fancy formula
set @func = sum(case when @t.Type = 1 then 1 else 0 end) * @t.Factor
-- plus a whole bunch of other, similar cases
else
set @func = 0;
select A, B, C, CalcField = @func(t)
from #MyTempTable t
join AnotherTable a on t.Field1 = a.Field1;
group by A, B, C
显然这里的语法不起作用,但是有什么可以实现我想要的吗?
表结构:
Foo FooChild Bar
--- -------- ---
ID ID ID
Date FooID Date
GroupID UserID UserID
Notes Amount GroupID
IsComplete
Foo
Date
在+上有唯一索引GroupID
FooChild
FooID
有一个到 Foo 的 FK,以及一个关于+的唯一索引UserID
,其中包括Amount
Bar
Date
在++上有一个唯一索引UserID
,GroupID
其中包括IsComplete
现在我需要创建一个报告,显示所有 FooChild 金额的总和以及任何给定日期范围内完整条形图的数量。用户还希望能够查看每个组或每个用户的统计信息。这似乎是编写视图的好地方:
create view vFooBar as
select f.Date, f.GroupID, fc.UserID, fc.Amount, b.IsComplete
from Foo f join FooChild fc on fc.FooID = f.ID
left join Bar b on f.Date = b.Date and f.GroupID = b.GroupID and fc.UserID = b.UserID
union
select b.Date, b.GroupID, b.UserID, x.Amount, b.IsComplete
from Bar b left join
(select f.Date, f.GroupID, fc.UserID, fc.Amount
from Foo f join FooChild fc on fc.FooID = f.ID) x
on x.Date = b.Date and x.GroupID = b.GroupID and x.UserID = b.UserID
(这就是我以这种方式编写视图的原因。)
现在我可以轻松地编写这样的查询:
select UserID, sum(Amount) FooAmount, sum(cast(IsCompleted as int)) CompletedBars
from vFooBar
where Date between @fromDate and @toDate
group by UserID
但是这里有一个障碍。一旦日期范围开始变得相对较大,执行计划就会变成梨形。它在 上使用日期索引Foo
,但不是在FooID
上使用索引FooChild
,而是执行聚集索引扫描,然后进行哈希匹配FooID
以与 上的结果连接Foo
。它在总体计划中做了两次;我猜每个聚合一次。那真的很痛。
我知道使用我创建的索引FooChild
可能效率不高,因为FooID
给定日期的值可能是离散的,尽管通常它们以大致相同的顺序插入。
我可以非规范化,将 and 添加Date
到GroupID
FooChild 表,然后索引这些列,我很确定这会大大提高性能。但这感觉不对。
还有其他想法吗?
我有两个表,我们称它们为 TableA 和 TableB。
TableA TableB
------ ------
ID ID
Date Date
Foo Bar
两个表的日期字段都有一个索引。现在,我想创建一个视图,该视图在 Date 字段上的两个表之间具有完整的外部联接,以显示Foo
该日期(如果有的话)的值以及该日期的值Bar
。
create view vFooBar as
select isnull(a.Date, b.Date) Date, a.Foo, b.Bar
from TableA a
full outer join TableB b on a.Date = b.Date
然后我运行一个查询:
select * from vFooBar where Date = '20141201'
这行得通......但是编译器合并a.Date
并b.Date
欺骗编译器不使用索引,我得到了一个涉及表扫描的可怕执行计划。
如何以查询它仍将使用我的索引的方式创建此视图?
我正在研究从 MS SQL 2012 升级到 2014 的好处。SQL 2014 的一大卖点是内存优化表,这显然使查询速度超快。
我发现内存优化表有一些限制,例如:
(max)
大小的字段timestamp
字段UNIQUE
限制这些都算作滋扰,但如果我真的想解决它们以获得性能优势,我可以制定一个计划。
真正的问题在于您无法运行语句,并且每次您将字段添加到索引列表中时ALTER TABLE
,您都必须经历这个繁琐的过程。INCLUDE
此外,您似乎必须将用户关闭系统才能对实时数据库上的 MO 表进行任何模式更改。
我觉得这完全令人发指,以至于我实际上无法相信微软会在这个功能上投入如此多的开发资金,却让它变得如此不切实际。这使我得出结论,我一定是弄错了。我一定误解了关于内存优化表的一些东西,这使我相信维护它们比实际情况要困难得多。
那么,我误解了什么?你用过MO表吗?是否有某种秘密开关或过程使它们易于使用和维护?
我有一个最近添加了 Filestream 数据的 SQL 数据库。现在我们每天对 QA 服务器进行备份/恢复,并且由于我添加了 Filestream 数据,这已经开始失败。所以我修改了“restore”语句以包含“with move”:
RESTORE DATABASE MyDb
FROM DISK = 'c:\somepath\mydb.bak'
WITH RECOVERY, REPLACE,
MOVE 'MyDb' TO 'f:\sql\MyDb.mdf',
MOVE 'MyDb_Log' TO 'f:\sql\MyBb_log.ldf',
MOVE 'MyDb_Filestream' TO 'f:\sql\MyDb_FS', NOUNLOAD, STATS = 10;
但这失败并出现以下错误:
文件“MyDb_Filestream”无法恢复到“f:\sql\MyDb_FS”。使用 WITH MOVE 标识文件的有效位置。
我已经在 Google 上到处寻找解决方案。 这个答案说您需要 3 个单独的 RESTORE DATABASE 语句,但没有说明它们是什么。这里接受的答案表明您需要手动复制整个 Filestream 文件夹,我觉得这很难相信。无论如何,它并不清楚这个过程是什么。
任何人都可以用白痴的分步说明向我说明,应该如何备份包含文件流的数据库,将其复制到另一台服务器并在那里恢复?
谢谢!
我有一个由 C#/Linq-To-Entities 代码生成的查询。与这种查询一样,它看起来非常丑陋,我怀疑将它包含在此处会有所帮助。但是我通过查询分析器运行它,发现 50.5% 的处理时间发生在“嵌套循环(内部连接)”步骤中,该步骤正在加入聚集索引搜索a2_AssessmentQuestion
(0.3%)和聚集索引扫描同一张表(13.1%)。
我承认我并不真正理解这个“嵌套循环连接”在做什么,但是为什么查询会在执行索引查找后立即对表进行扫描,而它正在查找的字段可以直接通过另一个索引获得究竟是必填字段?是的,我已经运行update statistics a2_AssessmentQuestion
了,但没有效果。
不是了解查询计划的专家,如果您能促使我回答相关问题,我将不胜感激;我可能只是不够了解,无法为您提供足够有用的信息。
谢谢!
编辑: FWIW,这是查询:
SELECT
[Project6].[ID] AS [ID],
[Project6].[ID2] AS [ID1],
[Project6].[ID1] AS [ID2],
[Project6].[ID3] AS [ID3],
[Project6].[ID5] AS [ID4],
[Project6].[ID7] AS [ID5],
[Project6].[ID6] AS [ID6],
[Project6].[ID8] AS [ID7],
[Project6].[ID9] AS [ID8],
[Project6].[ID11] AS [ID9],
[Project6].[ID10] AS [ID10],
[Project6].[ID12] AS [ID11],
[Project6].[ID13] AS [ID12],
[Project6].[Number] AS [Number],
[Project6].[ScholarAssessmentID] AS [ScholarAssessmentID],
[Project6].[C1] AS [C1],
[Project6].[GradingStyle] AS [GradingStyle],
[Project6].[PartID] AS [PartID],
[Project6].[C2] AS [C2],
[Project6].[ID4] AS [ID13],
[Project6].[Description] AS [Description],
[Project6].[Version] AS [Version],
[Project6].[DifficultyLevel] AS [DifficultyLevel],
[Project6].[AssessmentQuestionID] AS [AssessmentQuestionID],
[Project6].[GradingDueDate] AS [GradingDueDate],
[Project6].[C3] AS [C3],
[Project6].[AssessmentFormat] AS [AssessmentFormat],
[Project6].[C4] AS [C4],
[Project6].[Structure] AS [Structure],
[Project6].[Title] AS [Title],
[Project6].[C5] AS [C5],
[Project6].[AssessmentFormat1] AS [AssessmentFormat1],
[Project6].[C6] AS [C6],
[Project6].[Label] AS [Label]
FROM ( SELECT
[Extent1].[ID] AS [ID],
[Extent1].[ScholarAssessmentID] AS [ScholarAssessmentID],
[Extent1].[AssessmentQuestionID] AS [AssessmentQuestionID],
[Join1].[ID1] AS [ID1],
[Join1].[ID2] AS [ID2],
[Extent4].[ID] AS [ID3],
[Extent4].[PartID] AS [PartID],
[Extent4].[Number] AS [Number],
[Extent4].[DifficultyLevel] AS [DifficultyLevel],
[Extent4].[Structure] AS [Structure],
[Extent4].[GradingStyle] AS [GradingStyle],
[Extent5].[ID] AS [ID4],
[Extent5].[Description] AS [Description],
[Extent5].[Version] AS [Version],
[Extent6].[ID] AS [ID5],
[Extent6].[GradingDueDate] AS [GradingDueDate],
[Extent6].[Title] AS [Title],
[Join6].[ID3] AS [ID6],
[Join6].[ID4] AS [ID7],
[Extent9].[ID] AS [ID8],
[Extent10].[ID] AS [ID9],
[Extent10].[AssessmentFormat] AS [AssessmentFormat],
[Join10].[ID5] AS [ID10],
[Join10].[ID6] AS [ID11],
[Extent13].[ID] AS [ID12],
[Extent14].[ID] AS [ID13],
[Extent14].[AssessmentFormat] AS [AssessmentFormat1],
CAST( [Extent4].[Points] AS bigint) AS [C1],
CAST( [Extent1].[PointsAwarded] AS decimal(19,0)) AS [C2],
CAST( [Extent6].[DueDate] AS datetime2) AS [C3],
CAST( [Extent4].[Number] AS bigint) AS [C4],
[Join14].[Label] AS [Label],
CASE WHEN ([Extent4].[RubricWeight] IS NOT NULL) THEN CAST( [Extent4].[RubricWeight] AS int) ELSE 0 END AS [C5],
CASE WHEN ([Join14].[ScholarAssessmentAnswerID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C6]
FROM [dbo].[a2_ScholarAssessmentAnswer] AS [Extent1]
INNER JOIN (SELECT [Extent2].[ID] AS [ID1], [Extent2].[AssessmentID] AS [AssessmentID], [Extent3].[ID] AS [ID2]
FROM [dbo].[a2_ScholarAssessment] AS [Extent2]
LEFT OUTER JOIN [dbo].[a2_ScholarFNPAssessment] AS [Extent3] ON [Extent2].[ID] = [Extent3].[ID] ) AS [Join1] ON [Extent1].[ScholarAssessmentID] = [Join1].[ID1]
INNER JOIN [dbo].[a2_AssessmentQuestion] AS [Extent4] ON [Extent1].[AssessmentQuestionID] = [Extent4].[ID]
LEFT OUTER JOIN [dbo].[a2_AssessmentQuestionType] AS [Extent5] ON [Extent4].[QuestionTypeID] = [Extent5].[ID]
INNER JOIN [dbo].[a2_AssessmentPart] AS [Extent6] ON [Extent4].[PartID] = [Extent6].[ID]
INNER JOIN (SELECT [Extent7].[ID] AS [ID3], [Extent7].[AssessmentID] AS [AssessmentID], [Extent8].[ID] AS [ID4]
FROM [dbo].[a2_ScholarAssessment] AS [Extent7]
LEFT OUTER JOIN [dbo].[a2_ScholarFNPAssessment] AS [Extent8] ON [Extent7].[ID] = [Extent8].[ID] ) AS [Join6] ON [Extent1].[ScholarAssessmentID] = [Join6].[ID3]
INNER JOIN [dbo].[a2_Assessment] AS [Extent9] ON [Join6].[AssessmentID] = [Extent9].[ID]
LEFT OUTER JOIN [dbo].[a2_AssessmentType] AS [Extent10] ON [Extent9].[AssessmentTypeID] = [Extent10].[ID]
INNER JOIN (SELECT [Extent11].[ID] AS [ID5], [Extent11].[AssessmentID] AS [AssessmentID], [Extent12].[ID] AS [ID6]
FROM [dbo].[a2_ScholarAssessment] AS [Extent11]
LEFT OUTER JOIN [dbo].[a2_ScholarFNPAssessment] AS [Extent12] ON [Extent11].[ID] = [Extent12].[ID] ) AS [Join10] ON [Extent1].[ScholarAssessmentID] = [Join10].[ID5]
INNER JOIN [dbo].[a2_Assessment] AS [Extent13] ON [Join10].[AssessmentID] = [Extent13].[ID]
LEFT OUTER JOIN [dbo].[a2_AssessmentType] AS [Extent14] ON [Extent13].[AssessmentTypeID] = [Extent14].[ID]
LEFT OUTER JOIN (SELECT [Extent15].[ScholarAssessmentAnswerID] AS [ScholarAssessmentAnswerID], [Extent16].[Label] AS [Label]
FROM [dbo].[a2_ScholarAssessmentAnswerSelection] AS [Extent15]
INNER JOIN [dbo].[a2_AssessmentAnswers] AS [Extent16] ON [Extent15].[AssessmentAnswerID] = [Extent16].[ID] ) AS [Join14] ON [Extent1].[ID] = [Join14].[ScholarAssessmentAnswerID]
WHERE (1538 = [Join1].[AssessmentID]) AND ( NOT EXISTS (SELECT
1 AS [C1]
FROM ( SELECT
[Extent18].[ID] AS [ID]
FROM [dbo].[a2_AssessmentQuestion] AS [Extent17]
INNER JOIN [dbo].[a2_AssessmentQuestion] AS [Extent18] ON [Extent17].[PartID] = [Extent18].[PartID]
WHERE [Extent1].[AssessmentQuestionID] = [Extent17].[ID]
) AS [Project1]
WHERE ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[a2_ScholarAssessmentAnswer] AS [Extent19]
WHERE ([Extent1].[ScholarAssessmentID] = [Extent19].[ScholarAssessmentID]) AND ([Extent19].[AssessmentQuestionID] = [Project1].[ID])
)) OR (CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[a2_ScholarAssessmentAnswer] AS [Extent20]
WHERE ([Extent1].[ScholarAssessmentID] = [Extent20].[ScholarAssessmentID]) AND ([Extent20].[AssessmentQuestionID] = [Project1].[ID])
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[a2_ScholarAssessmentAnswer] AS [Extent21]
WHERE ([Extent1].[ScholarAssessmentID] = [Extent21].[ScholarAssessmentID]) AND ([Extent21].[AssessmentQuestionID] = [Project1].[ID])
)) THEN cast(0 as bit) END IS NULL)
))
) AS [Project6]
ORDER BY [Project6].[ID] ASC, [Project6].[ID2] ASC, [Project6].[ID1] ASC, [Project6].[ID3] ASC, [Project6].[ID5] ASC, [Project6].[ID7] ASC, [Project6].[ID6] ASC, [Project6].[ID8] ASC, [Project6].[ID9] ASC, [Project6].[ID11] ASC, [Project6].[ID10] ASC, [Project6].[ID12] ASC, [Project6].[ID13] ASC, [Project6].[ID4] ASC, [Project6].[C6] ASC
我试图包括执行计划,但这让我超过了 30,000 个字符的限制。
疯狂的是,我提供了 AssessmentID = 1538,这是查询中最有用的限制信息,但执行计划几乎忽略了这个事实,并且扫描了几乎所有其他连接表,仅按 AssessmentID 过滤作为事后的想法...
我有一个Foo
包含以下字段的表:
ID bigint not null identity(1,1),
SerializedValue nvarchar(max),
LongValue as TRY_CAST(SerializedValue as bigint)
现在我想在 LongValue 上创建一个索引,以便我可以轻松地查找代表数字的序列化值。
create nonclustered index IX_Foo on Foo(LongValue);
这向我吐出以下错误:
字符串或二进制数据将被截断。
是的,SerializedValue 中有现有数据。但是,祈祷,可以通过在计算字段上创建索引来截断什么?
我获得了一个 DMP 数据泵导出文件,可以导入到我的本地 Oracle 实例中。我试过运行这个命令行:
impdp full=Y 目录=DATA_PUMP_DIR dumpfile=MyDumpFile.dmp logfile=import.log
我得到错误:
ORA-31655: 没有为作业选择数据或元数据对象
ORA-39154: 来自外部模式的对象已从导入中删除
并且没有数据被导入。
根据我的谷歌搜索,一个可能的原因是我需要指定remap_schama
. 但我不知道 dmp 文件中架构的名称是什么。有什么简单的方法可以查出来吗?
编辑:我没有找到这个问题的解决方案,但我确实找到了解决方法......我找到了制作 DMP 的人,并从他那里得到了模式名称。remap_schema
根据他的定义指定,Hey Presto!
我的业务要求在TableA
引用时有一个 FK 字段TableB
。如果 中有一个值TableBID
,它应该是唯一的,但它不是强制性的,因此可能会有多个具有空值的记录。
是否可以使用索引或约束以某种方式在数据库级别强制执行这种类型的唯一性?
我有两台机器,每台都安装了 SQL Server 2008 的默认实例;每个都表现出不同的行为。
sqlcmd -Lc
,当 SQL Browser 服务未运行时,我在本地网络上的 SQL 服务器列表中看不到 PC1。当我启动 SQL 浏览器服务时,PC1 出现在列表中。sqlcmd -Lc
,我会在列表中看到 PC2,无论 SQL 浏览器服务是否正在运行。如果 SQL Browser 服务正在运行,我还会看到 PC2\SQLEXPRESS。为什么 PC1 的默认 SQL 实例没有出现在 SQL Server 列表中?
我在安装我们产品的软件安装包(使用 InstallShield/InstallScript 编写)时遇到了间歇性问题。在安装过程中,我们重新启动 SQL Browser 服务。大多数情况下,这工作正常。但偶尔——而且我还没有想出如何以可预见的方式重现——服务无法重新启动,我在“服务”管理器中发现服务状态设置为“禁用”。
有什么想法会导致服务被禁用,以及如何防止它发生?
我有一个大表(数千万到数亿条记录),出于性能原因,我们已将其拆分为活动表和存档表,使用直接字段映射,并且每晚运行存档进程。
在我们的代码中的几个地方,我们需要运行结合活动表和存档表的查询,几乎总是由一个或多个字段过滤(我们显然在两个表中都放置了索引)。为方便起见,有这样的视图是有意义的:
create view vMyTable_Combined as
select * from MyTable_Active
union all
select * from MyTable_Archive
但是,如果我运行类似的查询
select * from vMyTable_Combined where IndexedField = @val
在过滤之前,它将对 Active 和 Store中的所有内容进行联合@val
,这会降低性能。
@val
有没有什么聪明的方法可以在创建联合之前 使联合的两个子查询按每个过滤器查看?
或者,您可能会建议其他一些方法来实现我的目标,即一种简单有效的方法来获取由索引字段过滤的联合记录集?
编辑:这是执行计划(你可以在这里看到真实的表名):
奇怪的是,活动表实际上使用了正确的索引(加上 RID 查找?)但存档表正在执行表扫描!
我正在维护别人的代码。有一个存储过程每天或每周运行一次(取决于配置),它将一堆记录从活动表迁移到存档。但这不是一个真正的存档,因为有几个实时进程在 SQL 查询中包含存档表,为此目的已对其进行了适当的索引。
现在这个故事的历史是归档表越来越大,归档 SP 开始需要很长时间。所以有人决定在 SP 开始时删除存档表上的所有索引并在最后重新创建它们是一个好主意。当然,重新创建它们也需要很长时间,但可以说只要插入带有索引的新记录就可以了。
这种情况只是对我尖叫:“这是罪恶的! ”在运行时使用索引似乎是错误的,错误的,错误的。我敢肯定这不是罕见的情况,那么处理这种情况的“正确”方法是什么?
因此,我们有一个客户网站抱怨性能严重下降。我看了一眼,很明显问题是因为Somebody Else (grrrr) 设计了一个表,其中包含大约 2000 万条记录而没有聚集索引。
现在我想在该表上创建一个聚集索引 - 但在我的测试环境中,我的create index
命令已经运行了一个小时,但仍未完成。客户站点是一个 24/7 全天候工作的车间,在我创建索引时无法承受一个小时的停机时间。
是否有一些创建索引的蛮力方法可以快速完成工作,或者以某种不会在服务器繁忙时完全破坏服务器性能的智能方式来完成?
我们使用的是 SQL Server 企业版。