2017-09-08 43 views
0

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

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索引。它没有多大帮助。

+0

当尝试过滤数据时,聚簇索引没有什么帮助。特别是当您试图通过任何不是(或部分)集群密钥的其他列过滤数据时。我建议你研究'〜动态更改的过滤器'中可能的列,并为这些列创建非聚簇索引。 SELECT SUM(CNT) FROM(SELECT COUNT(*)CNT FROM T_1 WHERE〜动态改变〜 UNION ALL SELECT COUNT(*)CNT - –

+0

不知道的第一个查询,但是你可以重写为提高你的第二个查询 FROM T_2 WHERE〜动态变化〜)子句 –

+0

@RahulRichhariya谢谢大家,我会尝试更新结果。 –

回答

0

我做那么什么来解决这个问题,是

  1. 创建了几个指标与最常用和大约独特的领域包括在过滤器中使用的字段的其余部分,这防止不必要的内部联接where子句是不是索引

    CREATE INDEX 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(
    选择
    F_ID为ID,
    1 AS TBL
    FROM T_1 WHERRE〜动态变化〜
    UNION ALL
    SELECT
    F_ID为ID,
    2 AS TBL
    FROM T_2 WHERE〜动态变化的〜)为t
    ORDER BY ID
    偏移:行偏移FETCH NEXT:大小行仅对)
    选择
    F_ID,
    F_2,
    F_3,...,F_15
    FROM CTE
    INNER JOIN T_1 ON cte.id = F_ID AND TBL = 1
    UNION ALL
    SELECT
    F_ID,
    F_2,
    F_3,...,F_15
    FROM cte
    INNER JOIN T_2 ON cte.id = F_ID AND tbl = 2;

0

不知道更多关于有问题的领域和数据在那里这不能得到很好的回答,但这里有一些建议。

  • 你并不需要为10+领域建立联合indizes,您可以创建一个包含每个单个字段的索引。这很容易,但是当然存储系统需要更多空间。有些领域的索引没有多大意义,例如仅包含两个不同的值的字段

  • 打印出变成是缓慢和与MS SQL的查询分析器分析它们的查询(布尔,int字段由包含值01等用作布尔值)。微软有一个TechNet article解释如何做到这一点。 通过给出的信息,您可以决定优化查询的最佳方法,即需要添加哪些索引以加快速度。

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

+0

在数据库中进行分页并不差,它实际上可以节省大量RAM,I/O,网络时间和CPU时间,这对于数据库非常有用。而且,通过电线传输更多的数据比需要的是缓慢的原因。 –

+0

是一组组合索引不会更好,那么所有近似独特的字段单独索引?我的意思是我可以为1,2,3,4 + 2,3,4 + 3,4 + 4创建4个单独的索引,即使我们传递一个3值或2,3值,它们将被数据库引擎使用在我的理解中,它涵盖了更多的情况,然后只是一个。 –

+0

@UladzislauKuzmin它可能会更好,但这取决于。单个字段上的索引比没有索引要好,因此您应该检查“每个字段的单个索引”是否对您有意义。也正如你自己已经说过的,有10个以上的字段,组合的数量太多而无法创建所有可能的组合。在为字段创建指示符后,您可以监视应用程序的慢查询(不确定您是如何在MS SQL中设置的,但应该有类似于MySQL的慢查询日志),并根据描述来分析,以决定进一步的优化(索引,查询的变化...) – Lothar