Sql 关于优化使用视图的存储过程的速度的建议
基于之前的一篇文章,在(谢谢)的帮助下,我得到了下面的sql代码,它工作得很好,但速度很慢。有人能建议我如何加快速度并优化速度吗 我现在使用的是SQL Server Express 2008(不是我原来的问题中的2005) 这段代码的作用是从多个表中检索参数及其关联值,并以易于比较的形式旋转表。这对于两行数据中的一行很好,但现在我正在测试100行数据,运行GetJobParameters需要7分钟才能完成 如有任何建议,我们将不胜感激,并提前向您表示感谢Sql 关于优化使用视图的存储过程的速度的建议,sql,sql-server,tsql,stored-procedures,view,Sql,Sql Server,Tsql,Stored Procedures,View,基于之前的一篇文章,在(谢谢)的帮助下,我得到了下面的sql代码,它工作得很好,但速度很慢。有人能建议我如何加快速度并优化速度吗 我现在使用的是SQL Server Express 2008(不是我原来的问题中的2005) 这段代码的作用是从多个表中检索参数及其关联值,并以易于比较的形式旋转表。这对于两行数据中的一行很好,但现在我正在测试100行数据,运行GetJobParameters需要7分钟才能完成 如有任何建议,我们将不胜感激,并提前向您表示感谢 /*******************
/***********************************************************************************************
** CREATE A VIEW (VIRTUAL TABLE) TO ALLOW EASIER RETREIVAL OF PARMETERS
************************************************************************************************/
CREATE VIEW dbo.vParameters AS
SELECT m.MachineID AS [Machine ID]
,j.JobID AS [Job ID]
,p.ParamID AS [Param ID]
,t.ParamTypeID AS [Param Type ID]
,m.Name AS [Machine Name]
,j.Name AS [Job Name]
,t.Name AS [Param Type Name]
,t.JobDataType AS [Job DataType]
,x.Value AS [Measurement Value]
,x.Unit AS [Unit]
,y.Value AS [JobDataType]
FROM dbo.Machines AS m
JOIN dbo.JobFiles AS j ON j.MachineID = m.MachineID
JOIN dbo.JobParams AS p ON p.JobFileID = j.JobID
JOIN dbo.JobParamType AS t ON t.ParamTypeID = p.ParamTypeID
LEFT JOIN dbo.JobMeasurement AS x ON x.ParamID = p.ParamID
LEFT JOIN dbo.JobTrait AS y ON y.ParamID = p.ParamID
GO
-- Step 2
CREATE VIEW dbo.vJobValues AS
SELECT [Job Name]
,[Param Type Name]
,COALESCE(cast([Measurement Value] AS varchar(50)), [JobDataType]) AS [Val]
FROM dbo.vParameters
GO
/***********************************************************************************************
** GET JOB PARMETERS FROM THE VIEW JUST CREATED
************************************************************************************************/
CREATE PROCEDURE GetJobParameters
AS
-- Step 3
DECLARE @Params TABLE (
id int IDENTITY (1,1)
,ParamName varchar(50)
);
INSERT INTO @Params (ParamName)
SELECT DISTINCT [Name]
FROM dbo.JobParamType
-- Step 4
DECLARE @qw TABLE(
id int IDENTITY (1,1)
, txt nchar(300)
)
INSERT INTO @qw (txt)
SELECT 'SELECT' UNION
SELECT '[Job Name]' ;
INSERT INTO @qw (txt)
SELECT ',MAX(CASE [Param Type Name] WHEN ''' + ParamName
+ ''' THEN Val ELSE NULL END) AS [' + ParamName + ']'
FROM @Params
ORDER BY id;
INSERT INTO @qw (txt)
SELECT 'FROM dbo.vJobValues' UNION
SELECT 'GROUP BY [Job Name]' UNION
SELECT 'ORDER BY [Job Name]';
-- Step 5
--SELECT txt FROM @qw
DECLARE @sql_output VARCHAR (MAX)
SET @sql_output = '' -- NULL + '' = NULL, so we need to have a seed
SELECT @sql_output = -- string to avoid losing the first line.
COALESCE (@sql_output + txt + char (10), '')
FROM @qw
EXEC (@sql_output)
GO
@sql\u输出的输出:
SELECT
[Job Name]
,MAX(CASE [Param Type Name] WHEN '001' THEN Val ELSE NULL END) AS [001]
,MAX(CASE [Param Type Name] WHEN '002' THEN Val ELSE NULL END) AS [002]
,MAX(CASE [Param Type Name] WHEN '003' THEN Val ELSE NULL END) AS [003]
,MAX(CASE [Param Type Name] WHEN '004' THEN Val ELSE NULL END) AS [004]
,MAX(CASE [Param Type Name] WHEN '005' THEN Val ELSE NULL END) AS [005]
,MAX(CASE [Param Type Name] WHEN '006' THEN Val ELSE NULL END) AS [006]
,MAX(CASE [Param Type Name] WHEN '007' THEN Val ELSE NULL END) AS [007]
,MAX(CASE [Param Type Name] WHEN '008' THEN Val ELSE NULL END) AS [008]
,MAX(CASE [Param Type Name] WHEN '009' THEN Val ELSE NULL END) AS [009]
,MAX(CASE [Param Type Name] WHEN '010' THEN Val ELSE NULL END) AS [010]
,MAX(CASE [Param Type Name] WHEN '011' THEN Val ELSE NULL END) AS [011]
,MAX(CASE [Param Type Name] WHEN '012' THEN Val ELSE NULL END) AS [012]
,MAX(CASE [Param Type Name] WHEN '013' THEN Val ELSE NULL END) AS [013]
,MAX(CASE [Param Type Name] WHEN '014' THEN Val ELSE NULL END) AS [014]
,MAX(CASE [Param Type Name] WHEN '015' THEN Val ELSE NULL END) AS [015]
,MAX(CASE [Param Type Name] WHEN '016' THEN Val ELSE NULL END) AS [016]
,MAX(CASE [Param Type Name] WHEN 'Acceptance' THEN Val ELSE NULL END) AS [Acceptance]
,MAX(CASE [Param Type Name] WHEN 'AdditionalOptionsAperture1' THEN Val ELSE NULL END) AS [AdditionalOptionsAperture1]
,MAX(CASE [Param Type Name] WHEN 'AdditionalOptionsAperture2' THEN Val ELSE NULL END) AS [AdditionalOptionsAperture2]
,MAX(CASE [Param Type Name] WHEN 'AdditionalOptionsBarcode' THEN Val ELSE NULL END) AS [AdditionalOptionsBarcode]
,MAX(CASE [Param Type Name] WHEN 'AdditionalOptionsFiducial1' THEN Val ELSE NULL END) AS [AdditionalOptionsFiducial1]
,MAX(CASE [Param Type Name] WHEN 'AdditionalOptionsFiducial2' THEN Val ELSE NULL END) AS [AdditionalOptionsFiducial2]
,MAX(CASE [Param Type Name] WHEN 'AlignsFirstPcb' THEN Val ELSE NULL END) AS [AlignsFirstPcb]
,MAX(CASE [Param Type Name] WHEN 'Aperture1DefinedX' THEN Val ELSE NULL END) AS [Aperture1DefinedX]
,MAX(CASE [Param Type Name] WHEN 'Aperture1DefinedY' THEN Val ELSE NULL END) AS [Aperture1DefinedY]
还有200行
这是模式:
CREATE TABLE Machines (
MachineID UNIQUEIDENTIFIER PRIMARY KEY,
PrinterType NVARCHAR(255), --UNIQUEIDENTIFIER REFERENCES PrinterTypes(TypeId),
Name NVARCHAR(255),
[Desc] NVARCHAR(MAX),
HostName NVARCHAR(255),
IP NVARCHAR(64), -- allows IPv4 and IPv6
Serial NVARCHAR(10),
Location NVARCHAR(255) )
GO
CREATE TABLE JobFiles (
JobID UNIQUEIDENTIFIER PRIMARY KEY,
MachineID UNIQUEIDENTIFIER REFERENCES Machines(MachineID) ON DELETE CASCADE,
[Desc] NVARCHAR(MAX),
Name NVARCHAR(255),
JobOpen BIT,
[CreateDate] DATETIME ,
[ModifyDate] DATETIME ,
[CreatedByUser] NVARCHAR(64) ,
[ModifiedByUser] NVARCHAR(64) )
GO
CREATE TABLE JobParamType (
ParamTypeID UNIQUEIDENTIFIER PRIMARY KEY,
Name NVARCHAR(255),
[Desc] NVARCHAR(MAX),
JobDataType INT)
GO
CREATE TABLE JobParamGroup (
ParamGroupID UNIQUEIDENTIFIER PRIMARY KEY,
Name NVARCHAR(255),
[Desc] NVARCHAR(MAX))
GO
CREATE TABLE JobParams (
ParamID UNIQUEIDENTIFIER PRIMARY KEY,
ParamTypeID UNIQUEIDENTIFIER REFERENCES JobParamType(ParamTypeID) ON DELETE CASCADE,
ParamGroupID UNIQUEIDENTIFIER REFERENCES JobParamGroup(ParamGroupID) ON DELETE CASCADE,
JobFileID UNIQUEIDENTIFIER REFERENCES JobFiles(JobID) ON DELETE CASCADE,
IsEnabled BIT)
GO
-- Text based property
CREATE TABLE JobTrait (
ParamID UNIQUEIDENTIFIER PRIMARY KEY REFERENCES JobParams(ParamID) ON DELETE CASCADE,
Value NVARCHAR(MAX) )
GO
-- Numeric based property
CREATE TABLE JobMeasurement (
ParamID UNIQUEIDENTIFIER PRIMARY KEY REFERENCES JobParams(ParamID) ON DELETE CASCADE,
Value FLOAT,
Format NVARCHAR(20),
Unit NVARCHAR(MAX) )
在不深入讨论数据库模式设计细节的情况下,我的第一个问题是您是否在视图定义中使用的每个连接谓词上创建了索引 回应你的评论 非性能优化数据库的典型起点是:
关于SQL Server索引的精彩而简要的介绍,我建议您阅读您能发布@SQL\u输出包含的内容吗?你看过执行计划了吗?我添加了SQL Studio Manager在我运行“Print@SQL\u output”而不是“EXEC(@SQL\u output)”时允许我查看的内容。你能告诉我执行计划是什么意思吗?我是sql新手,学习曲线很陡。。。谢谢。在查询分析器中,打开查询菜单并选中包含实际执行计划。但是,看看您的@sql\u输出,我并不奇怪它需要很长时间。我怀疑任何索引都不能加快速度,但可以肯定的是,请仔细查看计划,并尝试通过创建适当的索引来至少解决每个表扫描。此外,您还可以在from子句之后发布所有内容吗?(不需要再包含200列,但是from和where子句可能提供更多的细节)。我已经修改了我的问题,包括模式和输出。谢谢,在外键中添加索引将速度从7分半提高到2秒!!!太好了,谢谢。@Belliez:另外,别忘了设计一个索引维护策略,以确保索引提供最佳性能。