关于优化使用视图的存储过程的速度的建议

时间:2010-04-13 10:08:16

标签: sql sql-server tsql stored-procedures view

基于之前的question并得到了Damir Sudarevic的大量帮助(谢谢),我有以下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_output的输出:

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) )

1 个答案:

答案 0 :(得分:1)

没有深入研究数据库模式设计的细节,我的第一个问题是你是否在视图定义中使用的每个连接谓词上创建了索引?

回应你的评论......

非性能调优数据库的典型起点是:

  1. 在每个表上创建一个聚簇索引,通常在主键上。
  2. 在所有外键上创建非聚簇索引,因为这些索引可能会在T-SQL Join子句中使用。
  3. 如果数据库上没有基本的索引策略,大多数查询都会执行表扫描(即触摸表中的每一行),这是一件坏事......

    有关SQL Server索引的简要介绍,建议您阅读Brad's Sure Guide to Indexes