SQL连接速度非常慢,数据量有限

时间:2015-02-19 12:30:37

标签: sql sql-server sql-server-2008 query-optimization

我们有一个非常慢的SQL运行,我想知道是否有人 关于加快速度的建议。

我们正在将大量表(21)中的数据收集到一个表中 供以后处理。这些表是临时表,仅存在于查询中。

所有表共享三列(USNDATASETINTERNAL_ID),以及 三者的组合在每个表中都是唯一的,但存在相同的值 在所有表格中。 INTERNAL_ID也可能是唯一的,但我不确定。

每个表包含六行数据,输出表还包含六行。

即,每个表都有以下数据,每个表中前三列相同,其余列包含每个表的不同数据。

USN DATASET INTERNAL_ID <more stuff>
20  BEN     67          ...
20  APP     68          ...
30  BEN     70          ...
30  BEN     75          ...
50  CRM     80          ...
70  CRM     85          ...

服务器是SQL 2008 R2,内存为4 x 2.3GHz内核,32GB内存 闲置,应该绰绰有余。

INSERT INTO查询本身大约需要3秒钟。

我能做些什么来找出代码速度如此之慢的原因,或者加快速度。如果在单个查询中我应该进行最大数量的连接?

CREATE TABLE #output (
  USN         INT,
  DATASET     VARCHAR(150),
  INTERNAL_ID INT,
  MASTER_DATA INT,
  EX1_DATA    INT,
  EX2_DATA    INT,
  EX3_DATA    INT,
-- More columns
)

完整输出表由247列组成,包含71个整数,11个浮点数,44个日期时间和121个varchars,总大小为16,996个字符!我希望每个varchar都有大约20-30个字符。

CREATE TABLE #master (
  USN         INT,
  DATASET     VARCHAR(150),
  INTERNAL_ID INT,
  MASTER_DATA INT,
-- More columns
)

CREATE TABLE #ex1 (
  USN         INT,
  DATASET     VARCHAR(150),
  INTERNAL_ID INT,
  EX1_DATA    INT,
-- More columns
)
CREATE TABLE #ex2 (
  USN         INT,
  DATASET     VARCHAR(150),
  INTERNAL_ID INT,
  EX2_DATA    INT,
-- More columns
)

-- Repeat for ex3 .. ex20

大多数ex表都是10-11列,其中一对在20-30列范围内。

-- Insert data into master, ex1..ex20

INSERT INTO #output(USN, DATASET, INTERNAL_ID, MASTER_DATA, EX1_DATA, EX2_DATA, ...)
  SELECT #master.USN, #master.DATASET, #master.INTERNAL_ID, #master.MASTER_DATA, #ex1.EX1_DATA, #ex2.EX2_DATA, ...
  FROM
    #master
    LEFT JOIN #ex1 ON #master.USN = #ex1.USN AND
                      #master.DATASET = #ex1.DATASET AND
                      #master.INTERNAL_ID = #ex1.INTERNAL_ID
    LEFT JOIN #ex2 ON #master.USN = #ex2.USN AND
                      #master.DATASET = #ex2.DATASET AND
                      #master.INTERNAL_ID = #ex2.INTERNAL_ID
    -- contine until we hit ex20

2 个答案:

答案 0 :(得分:1)

我会根据数据(唯一)在每个临时表上添加索引。

我只会从两个int列的索引开始,如果还不够,我会在索引中添加DATASET列。

有时你JOIN表所做的命令(或在之前版本的MS SQL中所做的)有很大的不同,所以从最小的表开始JOIN(如果可能的话)。

答案 1 :(得分:0)

  1. 如果每个表中只有一行具有给定的USN,DATASET,INTERNAL_ID,则每个连接序列的结果表的大小将呈指数增长。如果是这种情况,请考虑重新编写您的陈述,或者用一些更简单的陈述替换。
  2. 考虑在每个#ex1-20表中使用连接语句中具有最高基数的行的索引(或者甚至是两列或整个三重奏的复杂索引)
  3. 当然,如果在结果临时表中存在一些约束,那么每个这样的约束也需要一个索引。