我有一个如下所示的查询:
SELECT
ROUND(SUM(AGLR * BlokInsideAreaFactor), 2) AS AGLRSum,
ROUND(SUM(Vaarsaed * BlokInsideAreaFactor), 2) AS VaarsaedSum,
ROUND(SUM(Vintsaed * BlokInsideAreaFactor), 2) AS VintsaedSum,
ROUND(SUM(Oliefroe * BlokInsideAreaFactor), 2) AS OliefroeSum,
ROUND(SUM(Baelgsaed * BlokInsideAreaFactor), 2) AS BaelgsaedSum
.... (+ 10 more columns)
FROM
(
SELECT
AGLR,
Vaarsaed,
Vintsaed,
Oliefroe,
Baelgsaed,
.... (+ 10 more columns)
Round((CASE WHEN bloktema.AREAL > 0 THEN
omraade.Geom.STIntersection(bloktema.Geom).STArea() / bloktema.AREAL ELSE 0 END), 2)
AS BlokInsideAreaFactor
FROM [CTtoolsData].dbo.BlokAfgroedeGrp blokAfgroed
INNER JOIN [CTtoolsTema].dbo.bloktema2012 bloktema
ON (bloktema.bloknr = blokAfgroed.bloknr)
INNER JOIN [CTtoolsTema].dbo.Area omraade
ON omraade.Geom.STIntersects(bloktema.GEOM) = 1
where omraade.Id = 296
AND blokAfgroed.[Year] = 2012
) AS Q1
我进行嵌套选择的原因是因为我必须先计算“BlokInsideAreaFactor”,然后再将其与外部选择中的其他列值相乘。
我最初的想法是我会以这种方式优化查询,因为“BlokInsideAreaFactor”每行只计算一次,而不是每行十五次(每列一次)。问题是查询变得非常非常慢这样做。查询大约需要 15 分钟,包含大约 4000 行。不幸的是,我们有老化的硬件,并且正在 SQLServer 2012 Express 上运行查询。
我查看了索引,似乎无法进一步优化。为什么看起来像这样的查询会变得如此缓慢,最重要的是有办法优化它吗?
更新:
涉及的表格如下所示:
BlokAfgroedeGrp:
- 列:Id(主键、身份)、BlokNr、Year、AGLR、Vaarsaed、Vintsaed...等。
- 索引:在 Id 上聚集,在 BlokNr + Year 上唯一非聚集
Bloktema2012:
- 列:Id(主键、身份)、BlokNr、Geom(几何)+其他(不重要)
- 索引:在 Id 上聚集,在 Geom 上空间,非唯一 - 在 Id + BlokNr 上非聚集,非唯一 - 仅在 BlokNr 上非聚集。
区域:
- 列:Id(主键、身份)、Geom(几何)+其他(不重要)
- 索引:在 Id 上聚集,在 Geom 上空间
我确保索引上没有任何碎片。