带有“选择其中 x 不为空"的 SQL Server 视图需要很长时间才能完成 [英] SQL Server view with a 'select where x is not null' takes ages to complete

查看:38
本文介绍了带有“选择其中 x 不为空"的 SQL Server 视图需要很长时间才能完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个复杂的视图,描述如下:查看多个表.需要删除双打"由 1 个表定义

I have a complex view, which is described here: View of multiple tables. Need to remove "doubles" defined by 1 table

我在里面使用了一个Cross Apply,代码是这样的:(请检查上面的url以了解视图)

I used a Cross Apply in it, and the code is this: (please do check the url above to understand the view)

    SELECT    dbo.InstellingGegevens.INST_SUBTYPE
            , dbo.InstellingGegevens.INST_BRON
            , dbo.InstellingGegevens.INST_INSTELLINGSNUMMER
            , dbo.InstellingGegevens.INST_NAAM
            , dbo.InstellingGegevens.INST_KORTENAAM
            , dbo.InstellingGegevens.INST_VESTIGINGSNAAM
            , dbo.InstellingGegevens.INST_ROEPNAAM
            , dbo.InstellingGegevens.INST_STATUUT
            , dbo.InstellingGegevens.ONDERWIJSNIVEAU_REF
            , dbo.InstellingGegevens.ONDERWIJSSOORT_REF
            , dbo.InstellingGegevens.DATUM_TOT
            , dbo.InstellingGegevens.DATUM_VAN
            , dbo.InstellingGegevens.VERBOND_REF
            , dbo.InstellingGegevens.VSKO_LID
            , dbo.InstellingGegevens.NET_REF
            , dbo.Instellingen.Inst_ID
            , dbo.Instellingen.INST_TYPE
            , dbo.Instellingen.INST_REF
            , dbo.Instellingen.INST_LOC_REF
            , dbo.Instellingen.INST_LOCNR
            , dbo.Instellingen.Opt_KalStandaard
            , dbo.InstellingTelecom.INST_TEL
            , dbo.InstellingTelecom.INST_FAX
            , dbo.InstellingTelecom.INST_EMAIL
            , dbo.InstellingTelecom.INST_WEB
            , dbo.InstellingAdressen.SOORT
            , dbo.InstellingAdressen.STRAAT
            , dbo.InstellingAdressen.POSTCODE
            , dbo.InstellingAdressen.GEMEENTE
            , dbo.InstellingAdressen.GEM_REF
            , dbo.InstellingAdressen.FUSIEGEM_REF
            , dbo.InstellingAdressen.FUSIEGEM
            , dbo.InstellingAdressen.ALFA_G
            , dbo.InstellingAdressen.PROVINCIE
            , dbo.InstellingAdressen.BISDOM
            , dbo.InstellingAdressen.ARRONDISSEMENT
            , dbo.InstellingAdressen.GEWEST
            , dbo.InstellingContPersDirecteurs.AANSPREKING
            , dbo.InstellingContPersDirecteurs.CONTACTPERSOON
            , dbo.InstellingContPersDirecteurs.FUNCTIE
            , InstellingLogin.Inst_Gebruikersnaam
            , InstellingLogin.Inst_Concode
            , InstellingLogin.Inst_DirCode
            , InstellingLogin.DOSSNR
            , InstellingLogin.Instelling_ID
FROM dbo.InstellingGegevens 
RIGHT OUTER JOIN dbo.Instellingen 
    ON dbo.InstellingGegevens.INST_TYPE = dbo.Instellingen.INST_TYPE 
    AND dbo.InstellingGegevens.INST_REF = dbo.Instellingen.INST_REF 
    AND dbo.InstellingGegevens.INST_LOC_REF = dbo.Instellingen.INST_LOC_REF
    AND dbo.InstellingGegevens.INST_LOCNR = dbo.Instellingen.INST_LOCNR 
LEFT OUTER JOIN dbo.InstellingTelecom 
    ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingTelecom.INST_TYPE 
    AND dbo.InstellingGegevens.INST_REF = dbo.InstellingTelecom.INST_REF 
    AND dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingTelecom.INST_LOC_REF 
LEFT OUTER JOIN dbo.InstellingAdressen 
    ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingAdressen.INST_TYPE 
    AND  dbo.InstellingGegevens.INST_REF = dbo.InstellingAdressen.INST_REF 
    AND  dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingAdressen.INST_LOC_REF 
LEFT OUTER JOIN dbo.InstellingContPersDirecteurs 
    ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingContPersDirecteurs.INST_TYPE 
    AND dbo.InstellingGegevens.INST_REF = dbo.InstellingContPersDirecteurs.INST_REF 
    AND dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingContPersDirecteurs.INST_LOC_REF 
CROSS APPLY
      (SELECT  TOP (1) *
        FROM  InstellingLogin AS il
        WHERE Instellingen.INST_LOC_REF = il.Inst_Loc_REF 
            AND Instellingen.INST_LOCNR = il.Inst_Loc_Nr 
            AND Instellingen.INST_REF = il.Inst_InstellingIKON_REF 
            AND Instellingen.INST_TYPE = il.Inst_InstellingIKONType
        ORDER BY CASE 
                    WHEN il.datum_tot IS NULL 
                    THEN 0 ELSE 1 
                    END
                    , il.datum_tot DESC) InstellingLogin

这个视图在大约 1 秒内返回了大约 5.5k 行.这很快!

This view returns me about 5.5k rows, in about 1s. This is fast!

但是!

当我用 where 子句调用这个视图时:

When I call this view with a where clause:

SELECT *
  FROM [Tink].[dbo].[InstellingAlleDetails]
  where gemeente is not null and (DATUM_TOT is null or DATUM_TOT > GETDATE())
  order by GEMEENTE, POSTCODE,STRAAT, INST_NAAM

返回所有行需要 1 分 20 秒.

it takes 1min 20s to return all rows.

当我删除 gemeente is not null 部分时,它又需要 1 秒.

When I drop the gemeente is not null part, it takes again 1s.

Gemeente 是一个 varchar(255).我也用 Inst_Naam is not null 尝试过,这也花了大约 1 分 30 秒.

Gemeente is a varchar(255). I also tried it with Inst_Naam is not null and that also took about 1min 30s.

为什么这个 is not null 需要这么多时间?更重要的是:我该如何解决这个问题?

Why does this is not null take so much time? And more importantly: how do I fix this?

推荐答案

我不知道为什么.可能 SQL Server 提出的查询计划不太好.

I don't know why. Probably SQL Server comes up with a query plan that is not so good.

您可以尝试先在没有 gemeente is not null 的情况下运行查询并将结果放入临时表中,然后使用 gemeente is not null 查询临时表.

You could try to first run the query without gemeente is not null and put the result in a temp table and then query the temp table with gemeente is not null.

select *
into #TempTable
from YourView

select *
from #TempTable
where gemeente is not null

drop table #TempTable

这篇关于带有“选择其中 x 不为空"的 SQL Server 视图需要很长时间才能完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆