标签: optimization

优化:将变量声明移至程序顶部

在优化一些存储过程时,我与 DBA 坐下来讨论了一些具有高阻塞和/或高读/写活动的存储过程。

DBA 提到的一件事是我应该TABLE在存储过程的顶部声明所有变量(尤其是变量)以避免重新编译。

这是我第一次听说这个,并且在重新访问我们拥有的所有不同存储过程之前正在寻找一些确认。他称其为“延迟查看代码”,而重新编译正在锁定将导致阻塞的模式。

将所有变量声明移到存储过程的顶部是否会减少重新编译?

sql-server stored-procedures optimization sql-server-2008-r2

15
推荐指数
1
解决办法
2147
查看次数

为什么 OFFSET ... FETCH 和旧式 ROW_NUMBER 方案之间存在执行计划差异?

OFFSET ... FETCHSQL Server 2012 引入的新模型提供了简单且快速的分页。考虑到这两种形式在语义上相同且非常常见,为什么会有任何差异?

人们会假设优化器可以识别两者并将它们(简单地)优化到最大程度。

这是一个非常简单的案例,OFFSET ... FETCH根据成本估算,速度提高了约 2 倍。

SELECT * INTO #objects FROM sys.objects

SELECT *
FROM (
    SELECT *, ROW_NUMBER() OVER (ORDER BY object_id) r
    FROM #objects
) x
WHERE r >= 30 AND r < (30 + 10)
    ORDER BY object_id

SELECT *
FROM #objects
ORDER BY object_id
OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

偏移量获取.png

可以通过创建 CIobject_id或添加过滤器来改变此测试用例,但不可能消除所有计划差异。OFFSET ... FETCH总是更快,因为它在执行时做的工作更少。

sql-server optimization execution-plan sql-server-2012 offset-fetch

15
推荐指数
2
解决办法
3174
查看次数

连接是否在运行时优化为 where 子句?

当我写这样的查询时......

select *
from table1 t1
join table2 t2
on t1.id = t2.id
Run Code Online (Sandbox Code Playgroud)

SQL 优化器,不确定这是否是正确的术语,是否将其转换为...

select *
from table1 t1, table2 t2
where t1.id = t2.id
Run Code Online (Sandbox Code Playgroud)

本质上,SQL Server 中的 Join 语句只是一种更简单的编写 sql 的方法吗?或者它实际上是在运行时使用的?

编辑:我几乎总是,而且几乎总是,使用 Join 语法。我只是好奇会发生什么。

join sql-server optimization t-sql

15
推荐指数
2
解决办法
1928
查看次数

如何更快地查询这 2000 万条记录视图?

对于搜索功能,我使用的视图包含我需要搜索的所有表中的记录。该视图有近 2000 万条记录。针对这种观点的搜索花费了太多时间。

我应该在哪里寻找改善此视图的性能?

视图的粗略定义如下。它包括十三张桌子和大约三十个字段。

CREATE VIEW [dbo].[v_AllForSearch]
AS
SELECT 
  FT.firstField AS [firstField]
, FT.fld_primary AS [fld_primary]
, FT.fld_thirdField AS [thirdField]
, FT.fld_fourthField AS [fourthField]           
, ISNULL(ST.[fld_firstSearchField],'') AS [firstSearchField]
, ISNULL(TT.[fld_thirdSearch],'') AS thirdSearch
, ISNULL(TT.[fld_fourthSearch],'')AS fourthSearch
, ISNULL(TT.[fld_fifthSearch],'')AS fifthSearch
, ISNULL(FRT.[fld_sixthSearch],'') As [sixthSearch]
, ISNULL(FRT.[fld_seventhSearch],'') AS [seventhSearch]
, ISNULL(FRT.[fld_eightSearch],'')AS [eightSearch]
, ISNULL(FIT.[fld_nineSearch],'') AS [nineSearch]
, ISNULL(SIT.[fld_tenthSearch],'')AS [tenthSearch]
, ISNULL(SET.[fld_eleventhSearch],'') AS [eleventhSearch]
, ISNULL(ET.[twelthSearch],'')AS [twelthSearch]
, ISNULL(NT.[thirteenthSearch],'')AS [thirteenthSearch]
, ISNULL(NT.[fourteenSearch],'') AS [fourteenSearch]
, ISNULL(NT.[fifteenSearch],'') AS [fifteenSearch]
, ISNULL(NT.[sxteenSearch],'')  AS [sxteenSearch]
, …
Run Code Online (Sandbox Code Playgroud)

index sql-server optimization view

14
推荐指数
3
解决办法
8112
查看次数

SentryOne 计划浏览器是否有效?

SentryOne Plan Explorer是否像宣传的那样工作,是否合法?有什么问题或需要担心的事情吗?

与 SSMS 对估计执行计划视图的噩梦相比,它似乎以颜色显示了热路径。

我担心的是 - 它是否恶意或以其他方式修改任何数据?

编辑:我刚刚听说过它,以前从未听说过这家公司。

performance sql-server optimization execution-plan query-performance

14
推荐指数
4
解决办法
2493
查看次数

为什么这个查询不使用我的非聚集索引,我该如何做?

作为这个关于提高查询性能的问题的后续,我想知道是否有办法让我的索引默认使用。

此查询在大约 2.5 秒内运行:

SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
Run Code Online (Sandbox Code Playgroud)

这个运行在大约 33 毫秒内:

SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31' 
ORDER BY [DateEntered], [DeviceID];
Run Code Online (Sandbox Code Playgroud)

[ID] 字段 (pk) 上有一个聚集索引,[DateEntered],[DeviceID] 上有一个非聚集索引。第一个查询使用聚集索引,第二个查询使用我的非聚集索引。我的问题是两部分:

  • 为什么,因为两个查询在 [DateEntered] 字段上都有一个 WHERE 子句,服务器是否在第一个而不是第二个上使用聚集索引?
  • 即使没有orderby,如何在此查询中默认使用非聚集索引?(或者为什么我不想要这种行为?)

index sql-server optimization sql-server-2008-r2

14
推荐指数
2
解决办法
3万
查看次数

为什么在唯一索引扫描后使用聚合运算符

我有一个表,其中有一个针对不可为空值过滤的唯一索引。在查询计划中使用了 distinct。是否有一个原因?

USE tempdb

CREATE TABLE T1( Id INT NOT NULL  IDENTITY PRIMARY KEY ,F1 INT , F2 INT )
go
CREATE UNIQUE NONCLUSTERED INDEX UK_T1 ON T1 (F1,F2) WHERE F1 IS NOT NULL AND F2 IS NOT NULL 
GO
INSERT INTO  T1(f1,F2) VALUES(1,1),(1,2),(2,1)

SELECT DISTINCT   F1,F2 FROM T1 WHERE F1 IS NOT NULL AND F2 IS NOT NULL 
SELECT  F1,F2 FROM T1 WHERE F1 IS NOT NULL AND F2 IS NOT NULL  
Run Code Online (Sandbox Code Playgroud)

查询计划: 在此处输入图片说明

sql-server optimization filtered-index

14
推荐指数
1
解决办法
351
查看次数

其中列不喜欢多个值

我试图在 postgresql 数据库中选择记录,其中用户名不像字符串列表。

SELECT * FROM rails_db WHERE username NOT LIKE 'j%' AND username NOT LIKE '%eepy%';
Run Code Online (Sandbox Code Playgroud)

问题是有很多这样的值。有没有办法创建一个数组并说如下:

SELECT * FROM rails_db WHERE username NOT LIKE ARRAY[my values];
Run Code Online (Sandbox Code Playgroud)

postgresql optimization

14
推荐指数
3
解决办法
4万
查看次数

恒定扫描应用

这个问题是关于VALUES这里这里开始的构造的优化器行为探索的延续。我想问一下VALUESAPPLY这次。

使用CROSS APPLY别名作为需要在查询的各个部分中引用的表达式是常见的模式。例如:

CREATE TABLE #data (N int);
INSERT INTO #data VALUES (5), (4), (3), (2), (1);

SELECT d.N, c.[Square]
FROM #data d
    CROSS APPLY (VALUES (d.N * d.N)) c([Square])
WHERE c.[Square] BETWEEN 1 AND 10
ORDER BY c.[Square];
Run Code Online (Sandbox Code Playgroud)

我自己总是CROSS APPLY在这种情况下使用,但有时我会遇到包裹在 inline-TVF 和OUTER APPLY-ed 中的此类表达式。因此,出于好奇,我换CROSSOUTER的exampling查询

SELECT d.N, c.[Square]
FROM #data d
    OUTER APPLY (VALUES (d.N * d.N)) c([Square])
WHERE c.[Square] …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization database-internals

14
推荐指数
1
解决办法
362
查看次数

与索引相关的 NOT 逻辑的使用

根据 Microsoft 的数据库开发书70-433:Microsoft SQL Server 2008 数据库开发

前导通配符和NOT逻辑都不允许查询优化器使用索引来优化搜索。为了获得最佳性能,您应该避免使用NOT关键字和前导通配符。

所以我认为那是NOT INNOT EXISTS等等

现在关于这个SO问题,我认为@GBN 选择的解决方案会违反上面给出的声明。

显然,事实并非如此。

所以我的问题是:为什么?

index sql-server optimization

13
推荐指数
1
解决办法
1789
查看次数