我有一个这样的sql,但它会在sqlserver中运行17秒。
刚刚注册我的网络的100个用户刚刚同时执行这个sql(80%的cpu使用率),而且没关系。但是明天会超过1000个用户。
所以,我的问题是:
1:如何优化这个sql?
2:100用户80%的CPU使用率,1000用户会发生什么?
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRANSACTION;
WITH tempQuestion AS
(
SELECT
DISTINCT(CASE
WHEN qut.IsComplex=1 THEN qf.Id
WHEN qut.IsComplex=0 THEN qs.Id END) AS QuestionId,
(CASE
WHEN qut.IsComplex=1 THEN qf.Content
WHEN qut.IsComplex=0 THEN qs.Content END) AS QuestionContent,
(CASE
WHEN qut.IsComplex=1 THEN qf.Content
WHEN qut.IsComplex=0 THEN qs.Content END) AS QuetionContentOri,
qut.IsComplex AS IsComplex,
qut.Id AS QuestionTemplateId,
qut.Name AS QuestionTemplateName,
qp.KnowDotCode AS KnowDotCode,
(CASE
WHEN qs.QuestionFaceCode IS NULL THEN qp.Analysis
WHEN qs.QuestionFaceCode IS NOT NULL THEN '' END) AS Analyze,
(CASE
WHEN qs.QuestionFaceCode IS NULL THEN qp.SuitNumber
WHEN qs.QuestionFaceCode IS NOT NULL THEN '' END) AS SuitNumber,
(CASE
WHEN qs.QuestionFaceCode IS NULL THEN qp.Difficult
WHEN qs.QuestionFaceCode IS NOT NULL THEN '' END) AS Difficult,
(CASE
WHEN qs.QuestionFaceCode IS NULL THEN qp.Levels
WHEN qs.QuestionFaceCode IS NOT NULL THEN '' END) AS Levels,
(CASE
WHEN qs.QuestionFaceCode IS NULL THEN qp.Exposure
WHEN qs.QuestionFaceCode IS NOT NULL THEN '' END) AS Exposure,
--qp.Analysis AS Analyze,--浼氬鑷村鍚堥閲嶅
qs.Tag,
qc.Name AS QuestionCategoryName,
qu.Name AS UnitName,
qu.Name AS QuestionUnitName,
qu.Id AS UnitId,
qp.Fettle,
(CASE
WHEN qut.IsComplex=1 THEN ''
WHEN qut.IsComplex=0 THEN qp.CreatedDateTime END) AS CreatedDateTime,
(CASE
WHEN qut.IsComplex=1 THEN ''
WHEN qut.IsComplex=0 THEN qp.LastUseDateTime END) AS LastUseDateTime,
(CASE
WHEN qut.IsComplex=1 THEN ''
WHEN qut.IsComplex=0 THEN u.Name END) AS CreateName,
pqs.Id,
pqs.OrderInPaper,
pqs.Score as Point,
pqs.PaperStrategyId,
pqs.QuestionCategoryId,
pqs.QuestionUnitId,
pqs.KnowDotIds,
(CASE
WHEN qs.QuestionFaceCode IS NULL THEN qs.Answer
WHEN qs.QuestionFaceCode IS NOT NULL THEN('') END) AS CorrectAnswer
FROM EL_QuestionBank.QS_QuestionStem AS qs
LEFT JOIN EL_QuestionBank.QS_QuestionFace AS qf
ON qs.QuestionFaceCode=qf.Id
INNER JOIN EL_QuestionBank.QS_QuestionProperty AS qp
ON qp.QuestionStemCode=qs.Id
LEFT JOIN EL_Organization.[User] AS u
ON qp.CreatorCode=u.Id
INNER JOIN EL_QuestionBank.QuestionCategory AS qc
ON qc.Id = qp.SubjectCode
INNER JOIN EL_QuestionBank.QS_QuestionUnit AS qu
ON qu.Id = qp.QuestionUnitCode
INNER JOIN EL_QuestionBank.QS_QuestionUnitTemplate AS qut
ON qut.Id = qu.QuestionUnitTemplateCode
INNER JOIN EL_Paper.PaperQuestionStrategy AS pqs
ON ((qut.IsComplex=0 AND pqs.QuestionId=qs.Id) OR (qut.IsComplex=1 AND pqs.QuestionId=qf.Id))
WHERE pqs.PaperStrategyId='576222efa335483680e4e2e6e1c3d254'
)
SELECT * FROM tempQuestion
COMMIT TRANSACTION;
答案 0 :(得分:6)
您可以尝试替换
INNER JOIN EL_Paper.PaperQuestionStrategy AS pqs
ON ((qut.IsComplex=0 AND pqs.QuestionId=qs.Id) OR ( qut.IsComplex=1 AND pqs.QuestionId=qf.Id))
与
CROSS APPLY (SELECT * FROM EL_Paper.PaperQuestionStrategy pqs1
WHERE (qut.IsComplex=0 AND pqs1.QuestionId=qs.Id)
UNION ALL
SELECT * FROM EL_Paper.PaperQuestionStrategy pqs2
(qut.IsComplex=1 AND pqs2.QuestionId=qf.Id)
) AS pqs
这不能保证加快速度,但是我已经遇到了过去的情况,我已经看到通过使用UNION ALL替换OR条件来改善非平凡查询的性能。如果这可以作为评论,我宁愿这样建议,因为它不是一个明确的答案。如果您尝试它,请添加评论,告知它是否有帮助,伤害或没有任何区别。此外,这是我的头脑,所以一定要测试结果是否相同。
对于将此技术应用于类似情况的人,请注意您可能需要使用UNION
而不是UNION ALL
来提供与您要替换的代码完全相同的结果。在这种情况下,联合的两个选择是互斥的,因为一个只能包含IsComplex=0
的行,而另一个只能包含IsComplex=1
的行,所以UNION ALL
效果很好。 UNION ALL
通常会比UNION
更快,但您无法仅根据效果标准进行选择。你必须选择能产生你期望的结果的那个。