簡體   English   中英

如何針對時間性能優化此查詢?

[英]How can I optimize this query for time performance?

我正在處理大量數據:600萬行。 我需要查詢盡可能快地運行,但我不知道進一步優化。 我已經刪除了3個子查詢,並在10萬行的適度數據集上將其從11個小時以上移動到僅35分鍾。 見下文!

declare @UserId uniqueidentifier;
set @UserId = '936DA01F-9ABD-4d9d-80C7-02AF85C822A8';


select
    temp.Address_Line1,
    temp.Cell_Phone_Number,
    temp.City,
    temp.CPM_delt_acd,
    temp.CPM_delt_date,
    temp.Customer_Id,
    temp.Customer_Type,
    temp.Date_Birth,
    temp.Email_Business,
    temp.Email_Home,
    temp.First_Name,
    temp.Geo,
    temp.Home_Phone_Number,
    temp.Last_Name,
    temp.Link_Customer_Id,
    temp.Middle_Name,
    temp.Naics_Code,
    temp.Office_Phone_Number,
    temp.St,
    temp.Suffix,
    temp.Tin,
    temp.TIN_Indicator,
    temp.Zip_Code,

    crm_c.contactid as CrmRecordId, 
    crm_c.ownerid as OldOwnerId, 
    crm_c.ext_profiletype as old_profileType,
    coalesce(crm_fim.ownerid, @UserId) as OwnerId,
    2 as profileType,

    case 
        when
            (temp.Tin = crm_c.ext_retail_prime_taxid collate database_default 
            and temp.Last_Name = crm_c.lastname collate database_default)
        then
            ('Tin/LastName: '+temp.Tin + '/' + temp.Last_Name)
        when
            (temp.Customer_ID = crm_c.ext_customerid collate database_default)
        then
            ('Customer_ID: '+temp.Customer_ID)
        else
            ('New Customer: '+temp.Customer_ID)
    end as FriendlyName,

    case 
        when
            (temp.Customer_ID = crm_c.ext_customerid collate database_default)
        then
            0
        else
            1
    end as ForceFieldLock

from DailyProfile_Current temp

left join crm_contact crm_c 
    on (temp.Customer_ID = crm_c.ext_customerid collate database_default 
        or (temp.Tin = crm_c.ext_retail_prime_taxid collate database_default 
        and temp.Last_Name = crm_c.lastname collate database_default))
    and 0 = crm_c.deletionstatecode and 0 = crm_c.statecode    

left outer join crm_ext_ImportMapping crm_fim 
    on temp.Geo = crm_fim.ext_geocode collate database_default 
    and 0 = crm_fim.deletionstatecode and 0 = crm_fim.statecode

其中crm_contact是指向另一個數據庫中的視圖的同義詞。 該視圖從聯系表和contactextension表中提取數據。 我需要來自兩者的數據。 如果有必要,我可以把它分成兩個連接。 通常,以“ext_”開頭的列來自crm_contact視圖的擴展部分。

當我在DailyProfile_Current表中對100k行運行它時,大約需要35分鍾。 該表是一堆nvarchar(200)列,其中包含一個平面文件。 它很糟糕,但這是我繼承的。 我想知道使用真實的數據類型是否會有所幫助,但我希望可能的解決方案也不涉及。

如果DailyProfile_Current表中包含與連接條件不匹配的內容,則運行速度非常快。 如果表中充滿了與連接條件匹配的內容,則速度非常慢。

臨時表中有Customer_ID和Geo的索引。 crm_contact表上還有各種索引。 不過,我不知道索引對nvarchar(200)列有多大幫助。

如果它很重要,我正在使用Sql Server 2005。

任何想法都表示贊賞。

我肯定會把它分成2個查詢,因為或者函數有時會很慢。 此外,在這些列上放置一個非聚集索引(按行分組):

DailyProfile_Current:
Customer_ID 
Tin, Last_Name
Geo 

crm_contact:
ext_customerid,deletionstatecode,statecode
ext_retail_prime_taxid, lastname ,deletionstatecode,statecode

crm_ext_ImportMapping:
ext_geocode,deletionstatecode,statecode

為什么不嘗試通過Query Profiler運行它? 它可能會給你一些提示。
或者在查詢結果中包含執行計划並查看它。

從查詢的外觀我只能建議通過從JOIN子句移動OR並使用UNION ALL將結果合並為一。 至少,它可能會讓你知道兩種類型的JOIN的哪一種很慢,並從那里開始工作。

在查詢分析器中運行它並允許它為您創建索引。 我猜你至少有sql 2000.為什么不打破代碼中的一些功能。 例如,您可以在代碼中執行case語句。 但這是假設您正在編寫代碼查詢。 我發現拆分查詢並占用代碼中的一些負載會在運行時產生顯着差異。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM