慢速运行的SQL查询

时间:2014-10-31 02:15:39

标签: sql sql-server

我有一个这样的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;

1 个答案:

答案 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更快,但您无法仅根据效果标准进行选择。你必须选择能产生你期望的结果的那个。