我最近开始致力于索引我们数据库中的各种视图。通常,其中一些表仅用于连接,很少用于 where 或 order by 语句。这意味着我们正在创建多个索引(或一个较大的相对效率较低的索引),它们都以主键为键。我应该澄清一下,通过包含此表中的任何内容,没有位置或顺序,并且在我遇到问题的视图中没有键查找。
如果 SQL 有多个索引都以 tbl.ID 为键,它如何选择使用一个索引而不是另一个?我发现即使从索引中提取的数据相同,它也会因视图而异。一般来说,选择一个索引而不是另一个索引在效率上没有巨大的收益/损失;让我相信它选择了一个“足够好”的索引并继续前进(因为有很多键都来自同一列)。
此外,由于这个原因,是否应该避免使用相同的键创建多个索引?
我目前正在处理的具体问题是选择这样的索引:
CREATE NONCLUSTERED INDEX [index1]
ON a.tbl ([ID])
INCLUDE (number,name,year, ...)
Run Code Online (Sandbox Code Playgroud)
包含中有 14 列的地方(不幸的是,但根据我们当前的查询结构是必需的)
在更有效的索引上:
CREATE NONCLUSTERED INDEX [index2]
ON a.tbl ([ID])
INCLUDE (number,name,year, ...)
Run Code Online (Sandbox Code Playgroud)
包含中只有 5 列的地方。
两个索引都有视图需要的信息,但一个明显更小,使用效率更高。需要存在更大的索引来覆盖调用其中所有列(大约表的一半)的大量视图。
可能值得一提的是,我可以选择像上面那样创建一个海量索引,它几乎覆盖了所有视图,但效率略低于这些较小的索引。从我的测试来看,添加这些额外的索引似乎不会增加更新表的显着成本;所以我选择创建它们以获得小的性能提升。通常,它们会在需要时使用,但在某些情况下,优化器会无缘无故地选择效率较低的选项。
我正在尝试为我的公司优化汇总代码,但遇到了一个非常奇怪的问题。我将许多标量函数转换为 TVF,它们似乎都比原始函数运行得更快,这很棒。但是,在调用它们的查询中,它们最终的运行速度明显慢于原始查询。这是我的更新的基本概述:
SELECT col1, ..., colx,
(CASE WHEN x <= 0 OR y <= 0 OR z <= 0 OR z = x
THEN output
WHEN valX <= 0
THEN output
WHEN minimum.min < 1.0 THEN 1.0
ELSE minimum.min
END) AS Q,
FROM Tbl1...tblx (series of inner joins)
CROSS APPLY dbo.inlinemin(val1, val2) AS minimum
Run Code Online (Sandbox Code Playgroud)
这是原文的基本轮廓:
SELECT col1, ..., colx,
(CASE WHEN x <= 0 OR y <= 0 OR z <= 0 OR z = x
THEN output
WHEN valX …Run Code Online (Sandbox Code Playgroud) 我目前正在更新旧的标量值函数,希望能够提高它们的效率或将它们更改为内联 TVF。
在对我的重写进行故障排除时,我在原始代码中遇到了一些奇怪的问题,根据我对 SQL 中变量的理解,这似乎没有意义
如果我要写
Declare @var as Integer
Select @var = col1 from table
Run Code Online (Sandbox Code Playgroud)
然后这将始终返回 col1 中的最后一项。但是,在我正在使用的功能中,情况似乎并非如此。最初,有一个 where 子句根据输入更改结果,但是,删除它后,上述属性应该保持不变。在大多数情况下,确实如此,但也有一些情况并非如此。
大纲大致类似于以下内容:
create function f (
@var1 ... )
returns datatype
begin
Declare @temp1 ... (several vars declared here)
select @temp1 = col1, @temp2 = col2, ..., @tempX = max(colX) from(
select col1, col2, ... ,
colX * (case when name = 'X' then 1 else 0)
from table1
INNER JOIN table2 on ...
inner join table3 on ...
left …Run Code Online (Sandbox Code Playgroud)