案例:我有一个从数据库中搜索的应用程序。这是非常缓慢(超过40秒)。通过追踪我找到了一个查询。当我在SSMS中运行查询时,它需要2-3秒,但当我打开执行计划时,它会超过40秒。设计应用程序提供两种不同的语言(校对)。经过调查发现,当语言是英语(默认排序规则)时,应用程序可以“尽可能快”地工作(6-7秒),但是当语言发生变化时,很明显,SQL server会重新编译,每次响应都超过40秒。
问题:在排序规则更改后,我是否可以避免重新编译?
SQL Server 2014。
发布于 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.已经证实了情况就像我在这里描述的那样),那么用多个排序规则索引该列的唯一方法是创建非持久化计算列,以强制对所提供的每种语言进行排序。所以你可以有一个列是:
ALTER TABLE [dbo].[SomeTable]
ADD [ColumnNameFrench] AS ([ColumnName] COLLATE French_100_...);然后:
[ColumnNameFrench]上创建非聚集索引[ColumnName]中选择,但是如果用户选择“法语”,那么它将从[ColumnNameFrench]中选择。然后,它将能够在[ColumnNameFrench]上使用索引。希望您不要提供太多的语言选项,因为我认为索引的10个副本可能是很多的。
表:
-- 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]);简单存储过程:
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发布于 2018-11-20 03:55:01
这里读得很好
应用程序慢,在SSMS中快?
第一次尝试不同的SET选项=可能是不同的查询计划
应用程序可以有ARITHABORT=OFF;
SSMS default=ON…因此,您可以运行这个集合ARITHABORT来模拟app中的查询,并查看时间是否匹配。
https://dba.stackexchange.com/questions/222881
复制相似问题