2013-04-23 89 views
-1

我有两个SQL查询来计算不同id1值之间的id2值之间的同现现象。样本表看起来像使用SQL Server缓慢SQL查询

id1 | id2 
101 | 1 
101 | 2 
101 | 3 
102 | 2 
102 | 3 
102 | 4 
103 | 15 
103 | 3 
103 | 4 

和期望的输出是:

A B Count 
1 2 1 
1 3 2 
2 3 4 
1 4 2 
2 4 3 
3 4 4 
1 15 1 
2 15 2 
3 15 2 
4 15 1 

这两种解决方案在下面粘贴。

-- Solution 1 
SELECT bar.id2 AS A, foo.id2 AS B, COUNT(*) AS Count 
FROM 
    (SELECT * FROM TestTab) AS bar, 
    (SELECT * FROM TestTab) AS foo 
WHERE bar.id1 <> foo.id1 
    AND bar.id2 < foo.id2 
GROUP BY bar.id2, foo.id2 

-- Solution 2 
SELECT bar.id2 AS A, foo.id2 AS B, COUNT(*) AS Count 
FROM TestTab AS bar 
JOIN TestTab AS foo 
    ON bar.id1 <> foo.id1 
WHERE bar.id2 < foo.id2 
GROUP BY bar.id2, foo.id2 

两个查询工作在小表细(即,100 - 1000行),但我需要查询大得多表(例如,100.000行)。我想知道如何加快查询和提高性能。提前感谢任何指针。

- Create table TestTab and insert dummy data 
CREATE TABLE TestTab 
INSERT INTO TestTab VALUES 
    (101,1), 
    (101,2), 
    (101,3), 
    (102,2), 
    (102,3), 
    (102,4), 
    (103,15), 
    (103,3), 
    (103,4) 
+3

一般规则:where/join/group子句中使用的任何字段都应该有一个索引。 – 2013-04-23 15:53:06

+0

作为一个轻微抛开,我建议使用“INNER JOIN”你想排除NULL的地方 - 这也会强制使用ON子句。 – penguat 2013-04-23 16:01:32

+0

你有另外一张只有id2值的表吗?如果是的话,它叫什么? – 2013-04-23 16:05:35

回答

1

这两个查询都是连接和等价的。

第一个是隐式连接,并附加了子查询。如果SQL Server不优化子查询,它可能会变慢。

正如其他人已经观察到的那样,如果您尚未这样做,请将索引添加到连接条件列id1和where子句列id2

3

我建议在id2添加索引到TESTTAB(如果不存在的话),然后尝试运行以下:

select distinct id2 into #id2 from TestTab; 

SELECT bar.id2 AS A, foo.id2 AS B, COUNT(*) AS Count 
FROM #id2 AS bar 
JOIN #id2 AS foo ON bar.id2 < foo.id2 
JOIN TestTab AS buz ON bar.id2 = buz.id2 
JOIN TestTab AS fuz ON foo.id2 = fuz.id2 
WHERE buz.id1 <> fuz.id1 
GROUP BY bar.id2, foo.id2; 

(如果你已经有一个表上ID2的不同值它可以跳过创建临时表并用它来代替)。

+0

[SQLFiddle](http://www.sqlfiddle.com/#!6/59b19/5/2)查看相同的结果集。我添加了一个订单,以便于比较。为什么建议临时表和这些额外的连接? – 2013-04-23 18:01:00

+0

@OlafDietsche:是的,结果集应该匹配 - 这应该是不同的大型TestTab的性能。我期望原查询的性能与n * n成正比(其中n是TestTab中的行总数),而提出的查询的性能应该与d * d * 2 * n成正比(其中d是不同值的数量) - 我想。 – 2013-04-23 18:11:38

+0

因此,如果'id2'列中有很多重复的值,性能会更好。感谢你能这么快回复。 – 2013-04-23 18:14:04