我有一个这样的 sql,但它会在 sqlserver 中运行 17 秒。
刚才有100个用户登录我的网站同时执行这个sql(80% cpu usage),没问题,但明天会超过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;
最佳答案
你可以尝试更换
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
更快,但您不能仅根据性能标准进行选择。您必须选择能够产生预期结果的那个。
关于sql - 运行缓慢的sql查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26666542/