自我加入大表缓慢问题

时间:2018-01-19 05:58:58

标签: sql-server tsql

我有两张桌子,比如......

  • table1(cid,duedate,currency,value)
  • main_table1(cid)

我的查询如下所示,我发现每个cidtable1之间的共同关系包含300万条记录(cidduedate列是复合唯一的)并且main_table包含1500条记录,都是唯一的。

SELECT 
    b.cid, c.cid, 
    (COUNT(*) * SUM(b.value * c.value) - 
                SUM(b.value) * SUM(c.value)) /   
    (SQRT(COUNT(*) * SUM(b.value * b.value) - 
                     SUM(b.value) * SUM(b.value)) * 
     SQRT(COUNT(*) * SUM(c.value * c.value) - 
                     SUM(c.value) * SUM(c.value))
    ) AS correl_ij
FROM 
    main_table1 a  
JOIN 
    table1 AS b ON a.cid = b.cid 
JOIN 
    table1 AS c ON b.cid < c.cid 
                AND b.duedate = c.duedate
                AND b.currency = c.currency 
GROUP BY 
    b.cid, c.cid 

请建议如何优化此查询,因为它运行缓慢。

CREATE TABLE #table1(
    id int identity, 
    cid int NOT NULL,
    duedate date NOT NULL,
    currency char(3) NOT NULL,
    value float,
    PRIMARY KEY(id,currency,cid,duedate)
);

CREATE TABLE #main_table1(       
    cid int NOT NULL PRIMARY KEY,
    currency char(3)         
);

- #main table包含155000个cid记录,没有重复值

insert into  #main_table1 
values(19498,'ABC'),(19500,'ABC'),(19534,'ABC')

     INSERT INTO #table1(CID,DUEDATE,currency,value)
     VALUES(19498,'2016-12-08','USD',-0.0279702098021799) ,
    (19498,'2016-12-12','USD',0.0151285161000268),
    (19498,'2016-12-15','USD',-0.00965080868337728),
    (19498,'2016-12-19','USD',0.00808331709091531)

此表中有300万条记录表示不同的日期和cid,大部分的cid都出现在#main_table1中。

我正在使用a.cid&lt; b.cid删除a.cid和b.cid之间的重复关系因为我在每个cid之间导出了核心。

所以19498 - &gt;&gt; 19500核心化计算因此我不想要19500 - &gt; 19498因为它会相同但重复。

2 个答案:

答案 0 :(得分:1)

PK很傻。你为什么要将Iden包含在复合PK中,更不用说在第一个位置?除非你出于某种误导的原因而必须使用Iden,否则请丢弃Iden。

PRIMARY KEY(cid, currency, duedate)

或者自然键如果不同

答案 1 :(得分:1)

如果您经常在cid列上加入或排序,则可能需要该列上的聚簇索引或以该列开头的复合索引。

如果cid, duedate是唯一的,那么您可以考虑完全删除id

如果由于某种原因要保留id,请将其设为PRIMARY KEY NONCLUSTERED,并在cid, duedate上指定聚集索引。