如何提高动态构建SQL的性能

时间:2017-09-08 06:58:02

标签: sql sql-server query-performance

实际上,当我们通过java代码动态创建SQL时,我有点陷入问题,这意味着在where子句中使用的字段列表中没有一致性来放置正确的索引有一个巨大的延迟和性能损失。我们使用MSSql服务器作为历史数据的存储。目前的记录总数为3百万,肯定会增加。有没有办法优化以下SQL查询。任何帮助将非常感谢,因为我不能添加索引到所有可能的字段组合有10+。

SELECT
  F_ID,
  F_2,
  F_3,..., F_15 FROM T_1 WHERE ~dynamically changed~
UNION ALL
SELECT
  F_ID,
  F_2,
  F_3,..., F_15 FROM T_2 WHERE ~dynamically changed~
ORDER BY F_ID OFFSET 75 ROWS FETCH NEXT 25 ROWS ONLY`

`SELECT COUNT(*)
FROM (SELECT F_ID
      FROM T_1
      WHERE ~dynamically changed~
      UNION ALL SELECT F_ID
                FROM T_2
                WHERE ~dynamically changed~) clause

现在我有唯一的索引〜聚簇ID索引。它没什么用。

2 个答案:

答案 0 :(得分:0)

如果不了解有关字段及其中的数据,可以很好地回答这些问题,但这里有一些建议。

  • 您不需要为10个以上的字段创建组合的indizes,您可以创建包含每个字段的索引。这很容易实现,但当然在存储系统上需要更多的空间。有些领域的索引并没有多大意义,例如:只包含两个不同值的字段(boolean,int字段用作布尔值,包含值01等)

  • 打印出结果很慢的查询,并使用MS SQL的查询分析器对其进行分析。微软有一个TechNet article解释如何做到这一点。 根据给出的信息,您可以决定优化查询的最佳方法,即需要添加哪些索引来加快速度。

  • 您似乎在SQL中对结果进行了分页。您可以检查是否可以使用您用于演示文稿的编程语言。在这种情况下,您可以打开一个游标并遍历数据,只需执行一次所需的语句(第三个只计算显示的所有条目数的语句随光标一起免费提供)。

答案 1 :(得分:0)

所以我为解决这个问题所做的就是

  1. 创建了一些索引,其中使用最多且近似唯一的字段包括过滤器中使用的其余字段,这可以防止不必要的内部联接来获取不属于索引一部分的where子句中的数据

      

    创建IND_ IX_1 ON table_placeholder(F_1)INCLUDE(F_2,F_3,F_4);
      CREATE INDEX IX_2 ON table_placeholder(F_2)INCLUDE(F_1,F_3,F_4);

  2. 更改现有查询,以便首先执行限制/过滤操作,然后将连接应用于有限的数据集。在此阶段,查询计划是您优化中唯一的朋友。在我的特定示例中,新创建的查询看起来像

      

    WITH cte AS(
      SELECT id,tbl FROM(
              SELECT
                  F_ID为id,
                  1 AS tbl
          从T_1 WHERRE~动态改变〜
          UNION ALL
          SELECT
              F_ID为id,
              2 AS tbl
          从T_2那里〜动态改变〜)为t
      ORDER BY id
      OFFSET:偏移ROWS FETCH NEXT:仅限行数)
      SELECT
          F_ID,
          F_2,
          F_3,...,F_15
      来自cte
      INNER JOIN T_1 ON cte.id = F_ID AND tbl = 1
      UNION ALL
      SELECT
          F_ID,
          F_2,
          F_3,...,F_15
          来自cte
          INNER JOIN T_2 ON cte.id = F_ID AND tbl = 2;