J'ai une procédure stockée qui récupère des données en utilisant 20 tables. Exemple de la procédure:Comment optimiser cette procédure stockée dynamique
CREATE PROCEDURE GetEnquiries
(
@EnquiryDate DATETIME = NULL
)
AS
DECLARE @querySELECT VARCHAR(MAX) = ''
DECLARE @queryWHERE VARCHAR(MAX) = ''
DECLARE @queryExtraColumns VARCHAR(MAX) = ''
DECLARE @queryReturnResults VARCHAR(MAX) = ''
-----------------------------------------------------
--Create temp table
-----------------------------------------------------
SET @querySELECT = '
CREATE TABLE #tempResults
(
EnquiryId INT,
Cost Decimal(18,2),
CustomerName VARCHAR(50),
EnquiryStatus VARCHAR(50),
ContactNumber VARCHAR(50),
NumberOfVisits INT
) '
-----------------------------------------------------
--Insert into temp table
-----------------------------------------------------
SET @querySELECT = '
INSERT INTO #tempResults
(
EnquiryId ,
Cost ,
CustomerName ,
EnquiryStatus ,
ContactNumber
) '
-----------------------------------------------------
--SELECT
-----------------------------------------------------
SET @querySELECT = '
SELECT
e.EnquiryId ,
e.Cost ,
c.CustomerName ,
e.EnquiryStatus ,
c.ContactNumber
FROM Enquiry e
INNER JOIN Customers c ON e.CustomerId = c.CustomerId '
-----------------------------------------------------
-- WHERE
-----------------------------------------------------
IF(@EnquiryDate IS NOT NULL)
BEGIN
SET @queryWHERE = @queryWHERE + ' CONVERT(VARCHAR(10),e.EnquiryDate,23) >= ' + ''''+ CONVERT(VARCHAR(10),@EnquiryDate,23) + ''''
END
--- There are at least 14 parameters used in WHERE operation the above is just one of them
-----------------------------------------------------
-- Count NumberOfVisits
-----------------------------------------------------
SET @queryExtraColumns = '
;WITH NumberOfVisits AS
(
SELECT t.EnquiryId, COUNT(EnquiryId) AS NumberOfVisits
FROM NumberOfVisits v
INNER JOIN #tempResults t ON v.EnquiryId = t.EnquiryId
GROUP BY t.EnquiryId
)
UPDATE #tempResults
SET NumberOfVisits = u.NumberOfVisits
FROM #tempResults t
INNER JOIN NumberOfVisits u ON u.EnquiryId = t.EnquiryId
'
-----------------------------------------------------
-- return the results
-----------------------------------------------------
SET @queryReturnResults = '
SELECT
EnquiryId ,
Cost ,
CustomerName ,
EnquiryStatus ,
ContactNumber ,
NumberOfVisits
FROM #tempResults t
'
-----------------------------------------------------
-- Combine all the strings + DROP the temp table
-----------------------------------------------------
-- PRINT( @querySELECT + ' WHERE ' + @queryWHERE + @queryExtraColumns + @queryReturnResults + ' DROP TABLE #tempResults ')
EXEC(@querySELECT + ' WHERE ' + @queryWHERE + @queryExtraColumns + @queryReturnResults + ' DROP TABLE #tempResults ')
Quelques faits:
La procédure ci-dessus est la forme simple de la procédure stockée je travaille.
J'utilise SQL Server 2008
Ma procédure actuelle a 15 paramètres, tous sont utilisés dans la clause WHERE. Si la valeur est fournie pour un paramètre, le paramètre est inclus dans la clause WHERE sinon.
Il y a au moins 10 colonnes dont la valeur provient de la condition GROUP BY comme celle "NumberOfVisits" donnée dans la procédure ci-dessus.
J'ai des index sur toutes les clés primaires & Clés étrangères.
Je index sur les toutes les colonnes qui sont utilisées dans la clause WHERE.
Je index sur les toutes les colonnes qui sont utilisées dans la clause GROUP BY.
Questions:
Q1: Est-ce est selon les meilleures pratiques pour créer des procédures stockées dynamiques suivant modèle ci-dessus?
Q2: Je suis le SQL de sortie de cette procédure en utilisant: - IMPRIMER (@querySELECT + '+' OÙ @queryWHERE + @queryExtraColumns + @queryReturnResults + 'DROP TABLE #tempResults') quand je cours que SQL a pris le même temps qui a été pris par la procédure stockée, pourquoi? n'est pas le SQL devrait prendre moins de temps? pourquoi il n'y a pas de différence?
Q3: Est-ce ce qui précède est la meilleure pratique pour obtenir la valeur des colonnes de synthèse (les « NumberOfVisits »)?
Q4: est ce qui précède est la meilleure façon de créer la clause WHERE dynamique?
Q5: Puis-je éviter l'utilisation de la table temporaire en utilisant une autre dans le scénario ci-dessus?
Q6: Que puis-je faire pour optimiser cette procédure?
S'il vous plaît pardonnez-moi, si ma question n'est pas claire ou pas une bonne question.
Merci pour votre temps précieux & aide.
[La malédiction et les bénédictions du SQL dynamique] (http://www.sommarskog.se/dynamic_sql.html) – Oded