sql - 运行缓慢的sql查询

标签 sql sql-server

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

相关文章:

java - 使用Spring批量选择

c# - 使用存储过程从 SQL Server 返回数据

java - SQL Server JDBC : unable to create new native thread

sql-server - SQL 在作为 SP 执行时挂起,但作为 SQL 则正常

c# - "Cannot implicitly convert type IDbConnection to SqlConnection"

sql - 每周总金额

sql - 使用哪个索引

sql - 为什么 ISNUMERIC (',' ) 是真的?

c# - 数组排序和SQL排序

c# - 将 DateTime 与数据库中存储的日期进行比较