首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >服务器级别上的Server执行计划

服务器级别上的Server执行计划
EN

Database Administration用户
提问于 2018-11-19 13:29:15
回答 2查看 94关注 0票数 1

案例:我有一个从数据库中搜索的应用程序。这是非常缓慢(超过40秒)。通过追踪我找到了一个查询。当我在SSMS中运行查询时,它需要2-3秒,但当我打开执行计划时,它会超过40秒。设计应用程序提供两种不同的语言(校对)。经过调查发现,当语言是英语(默认排序规则)时,应用程序可以“尽可能快”地工作(6-7秒),但是当语言发生变化时,很明显,SQL server会重新编译,每次响应都超过40秒。

问题:在排序规则更改后,我是否可以避免重新编译?

SQL Server 2014。

EN

回答 2

Database Administration用户

发布于 2018-11-19 14:33:00

这里有一些令人困惑的信息。例如,这是没有意义的:

我打开执行计划,时间超过40秒。

你说“我启动执行计划”是什么意思?如果您正在讨论SSMS中的“包含实际执行计划”选项,那么是的,对于SSMS来说,准备和绘制图形执行计划确实需要更长的时间。当然,第一次启用此选项需要更长的时间。您运行了几次查询吗?

此外,你还说:

当我在SSMS中运行查询时,需要2-3秒。

然后说:

我发现,当语言是英语(默认排序)应用程序工作“尽快”(6-7秒)。

2-3秒不是“越快越好”吗?或者应用程序是否为其处理添加了3-5秒?

无论哪种方式:

当它的语言发生变化时,很明显,SQL server会重新编译,每次响应都超过40秒。

不,不是“显然”。重新编译并不能解释每次执行时30+的第二个差异。但是,他们是如何改变校对的呢?这个动态SQL是使用nothing或COLLATE Latin1_General...,然后使用COLLATE other_lang...作为另一种语言(S)吗?不确定如何更改查询的排序规则。尽管如此,如果“排序规则”实际上是以我刚才描述的方式改变的,那么有一件事可以解释这种差异):如果列是索引的,那么我猜该列的排序规则是[SQL_]Latin1_General_...,因此索引也是基于英语排序的。例如,如果提交的查询使用COLLATE French_...强制执行不同的排序规则,则查询不能使用索引,因为行可能以不同的顺序排列。

如果我对正在发生的事情是正确的(O.P.已经证实了情况就像我在这里描述的那样),那么用多个排序规则索引该列的唯一方法是创建非持久化计算列,以强制对所提供的每种语言进行排序。所以你可以有一个列是:

代码语言:javascript
复制
ALTER TABLE [dbo].[SomeTable]
  ADD [ColumnNameFrench] AS ([ColumnName] COLLATE French_100_...);

然后:

  1. [ColumnNameFrench]上创建非聚集索引
  2. 更新应用程序代码/查询,这样如果有人选择"English",那么它就从[ColumnName]中选择,但是如果用户选择“法语”,那么它将从[ColumnNameFrench]中选择。然后,它将能够在[ColumnNameFrench]上使用索引。

希望您不要提供太多的语言选项,因为我认为索引的10个副本可能是很多的。

示例

表:

代码语言:javascript
复制
-- DROP TABLE #Test;
CREATE TABLE #Test
(
  [TestID] INT IDENTITY(1, 1) PRIMARY KEY,
  [SomethingEnglish] NVARCHAR(50) COLLATE Latin1_General_100_CI_AS_SC,
  [SomethingFrench] AS ([SomethingEnglish] COLLATE French_100_CI_AS_SC),
  [SomethingHebrew] AS ([SomethingEnglish] COLLATE Hebrew_100_CI_AS_SC)
);

CREATE INDEX [IX_#Test_SomethingEnglish] ON #Test ([SomethingEnglish]);
CREATE INDEX [IX_#Test_SomethingFrench] ON #Test ([SomethingFrench]);
CREATE INDEX [IX_#Test_SomethingHebrew] ON #Test ([SomethingHebrew]);

简单存储过程:

代码语言:javascript
复制
GO
CREATE PROC dbo.Search
(
  @Search  NVARCHAR(500),
  @Language INT
)
AS
SET NOCOUNT ON;

DECLARE @SQL NVARCHAR(MAX);

SET @SQL = N'
SELECT tmp.[TestID]
FROM   #Test tmp
WHERE  tmp.[Something' + 
CASE @Language
  WHEN 1 THEN N'Hebrew'
  WHEN 2 THEN N'French'
  ELSE N'English'
END + N'] = @SearchTerm;';

EXEC sp_executesql
  @SQL,
  N'SearchTerm NVARCHAR(500)',
  @SearchTerm = @Search;
GO
票数 2
EN

Database Administration用户

发布于 2018-11-20 03:55:01

这里读得很好

应用程序慢,在SSMS中快?

第一次尝试不同的SET选项=可能是不同的查询计划

应用程序可以有ARITHABORT=OFF;

SSMS default=ON…因此,您可以运行这个集合ARITHABORT来模拟app中的查询,并查看时间是否匹配。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/222881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档