SQL Server提高了加入大小表的性能

时间:2018-02-13 01:41:49

标签: sql sql-server

我正在尝试加入两个表:

表1 :( 9亿行(106 GB)。并且,id1,id2,id3,id4是群集主键,houseType是字符串)

+-----+-----+-----+------------+--------+
| Id1 | id2 | id3 | id4        |  val1  |
+-----+-----+-----+------------+--------+
| ac  |  15 | 697 | houseType1 | 75.396 |
+-----+-----+-----+------------+--------+
| ac  |  15 | 697 | houseType2 | 20.97  |
+-----+-----+-----+------------+--------+
| ac  |  15 | 805 | houseType1 | 112.99 |
+-----+-----+-----+------------+--------+
| ac  |  15 | 805 | houseType2 | 53.67  |
+-----+-----+-----+------------+--------+
| ac  |  27 | 697 | houseType1 | 67.28  |
+-----+-----+-----+------------+--------+
| ac  |  27 | 697 | houseType2 | 55.12  |
+-----+-----+-----+------------+--------+

表2非常小,有150行。并且,val1,val2是群集主键。

+------+------+---------+
| val1 | val2 | factor1 |
+------+------+---------+
| 0    | 10   | 0.82    |
+------+------+---------+
| 10   | 20   | 0.77    |
+------+------+---------+
| 20   | 30   | 0.15    |
+------+------+---------+

我需要什么:

对于每一个" val1"在table1中,应该找到它所属的table2中的[val1,val2]范围及其关联的" factor1" table2中应返回table2,它将用于进一步的聚合计算。

我的查询示例:

 Select a.id1, a.id2, a.id3, a.id4, 
         max(case when a.val1 >= b.val1 and a.val1 < b.val2 then  b.factor1 * a.val1
                else null
            end ) as result
 From Table1 as a,
      Table2 as b
 Group by  a.id1, a.id2, a.id3, a.id4

例如,一行:

   ac ,  15, 697, houseType2, 20.97 in table1
   0.15 should be returned from table2 because 20.97 in range [20, 30] in table2.

查询中没有加入操作,因为我不知道如何在此处使用加入。我只需要在table2中查找val1的因子。

在SQL Server中,运行速度非常慢,超过3小时。

我也得到了:

   Warning: Null value is eliminated by an aggregate or other SET operation. 

有人可以帮我这个吗?

感谢

2 个答案:

答案 0 :(得分:1)

这会减少你的记录集:

Select a.id1, a.id2, a.id3, a.id4, 
         b.factor1 * a.val1 as result
 From Table1 a inner join
      Table2 b on a.val1 >= b.val1 and a.val1 < b.val2

这样,您只能从a获得每条记录的b单条记录。这至少是改善性能问题的一个开始。

不需要MAX,因为您正在加入以获得单个记录。

答案 1 :(得分:0)

我倾向于将其表达为子查询或横向连接:

Select a.id1, a.id2, a.id3, a.id4, b.factor1 * a.val1 as result
From Table1 a cross apply
     (select b.*
      from Table2 b
      where a.val1 >= b.val1 and a.val1 < b.val2 
     ) b;

聚合是不必要的,因为四个键构成了主键。