Как я могу заставить этот скрипт SQL работать быстрее? - PullRequest
0 голосов
/ 04 марта 2011

Я написал скрипт для исправления значений в таблицах. Но для того, чтобы закончить, нужно вечно ... на самом деле никогда не видел, чтобы он закончился ... просто висел там ... любой момент, как его оптимизировать, будет оценен.

Существует 2 таблицы: FundCorrespondencePreference, в которых могут быть отмечены некоторые из столбцов IDContacts в записях. Если они проверены, соответствующие записи должны присутствовать в таблице ContentManagementRights (с почти идентичными полями, кроме некоторых).

Идея состоит в том, чтобы пройти ContentManagemtnRights и найти все уникальные записи, объединяющие 4 столбца, выберите некоторые значения столбцов и соберите всех пользователей из FundCorrespondencePreference table, затем проверьте, отмечен ли этот пользователь в этой коллекции, вернитесь к таблице ContentManagementRights и проверьте, есть ли такая запись, если нет, вставьте запись с соответствующими значениями в столбцы.

Надеюсь, я объяснил это более или менее связно. В любом случае, ценю ваше время и предложения. Вот сценарий:

--the script will check if any of the contacts for a partner in FundCorrespondencePreferences are missing in ContentManagementRight table
-- some of the contacts in FundCorrespondencePreference just not appear in ContentManagementRight as checked

    declare @IDFundInfo char(30)
    declare @IDCompany char(30)
    declare @IDFundTransactionParameter char(30)
    declare @IDContentManagement char(30)
    declare @IDUserInfo char(30)
    declare @ID char(30)

    declare @curContentManagementRights cursor
    set @curContentManagementRights = cursor fast_forward for
    --first select distinct records from ContentManagementRights for IDFundInfo, IDCompany,IDFundTransactionParameter and IDContentManagement where
    --bFundLevelAccess == 0
    SELECT distinct
       ContentManagementRights.IDFundInfo, 
       ContentManagementRights.IDCompany, 
       ContentManagementRights.IDFundTransactionParameter, 
       ContentManagementRights.IDContentManagement
    FROM ContentManagementRights 
    WHERE     
       (ContentManagementRights.bFundLevelAccess = 0)
    ORDER BY 
       idfundinfo, idcompany,idfundtransactionparameter, idcontentmanagement

    open @curContentManagementRights;
    fetch from @curContentManagementRights into @IDFundInfo, @IDCompany,@IDFundTransactionParameter,@IDContentManagement

    WHKLE @@fetch_status = 0
    BEGIN
        --get all IDContactInfo for the chosen fund, partnerid,fundtranactionparameterid from fundcorrespondencepreference table + make sure that at least one correspTO parameter

       declare @curFundCorrespondencePreference cursor
       set @curFundCorrespondencePreference = cursor fast_forward for 
         SELECT     
             UserInfo.IDUserInfo
         FROM         
             FundCorrespondencePreference 
         INNER JOIN
             FundTransactionParameter ON FundCorrespondencePreference.IDFundTransactionParameter = FundTransactionParameter.IDFundTransactionParameter 
         INNER JOIN
             ContactInfo ON FundCorrespondencePreference.IDContactInfo = ContactInfo.IDContactInfo 
         INNER JOIN
             UserInfo ON ContactInfo.IDContactInfo = UserInfo.IDContactInfo 
         INNER JOIN
             UserGroupInfo ON UserInfo.IDUserInfo = UserGroupInfo.IDUserInfo 
         INNER JOIN
             GroupInfo ON UserGroupInfo.IDGroupInfo = GroupInfo.IDGroupInfo
         WHERE     
            (FundTransactionParameter.IDFundInfo = @IDFundInfo) 
            AND (FundCorrespondencePreference.IDCompany = @IDCompany) 
            AND (FundCorrespondencePreference.IDFundTransactionParameter = @IDFundTransactionParameter) 
            AND (FundCorrespondencePreference.bEmail = 1) 
            AND (GroupInfo.sName = N'Xtranet Partner Group') 
            OR (FundCorrespondencePreference.bFax = 1) 
            OR (FundCorrespondencePreference.bLetterTo = 1) 
            OR (FundCorrespondencePreference.bLetterCc = 1) 
            OR (FundCorrespondencePreference.bEmailCc = 1) 
            OR (FundCorrespondencePreference.bFaxCc = 1)

          --go through all the contacts chosen from FundCorrespondencePreference table and 
          --if not present in ContentManagementRight table, insert into the table record with previously selected parameters
          open @curFundCorrespondencePreference;
          fetch from @curFundCorrespondencePreference into @IDUserInfo

          WHILE @@fetch_status = 0
          BEGIN
            if 
               (Select Count(IDContentManagementRights) 
                from ContentManagementRights 
                where 
                   IDContentManagement = @IDContentManagement 
                   and IDFundInfo = @IDFundInfo 
                   and IDCompany = @IDCompany 
                   and IDUserInfo = @IDUserInfo) = 0
             begin
            --insert a new record in ContentManagementRights if there is none for chosen parameters
            Exec GetNextID 'ContentManagementRights', @ID output
            INSERT INTO ContentManagementRights (IDContentManagementRights,IDContentManagement,IDFundInfo,IDCompany,sCreatedBy,dtCreatedDate,sUpdatedBy,dtUpdatedDate,IDUserInfo,IDFundTransactionParameter,bFundLevelAccess)
            VALUES (@ID,@IDContentManagement,@IDFundInfo,@IDCompany,'admin',GETDATE(),'admin',GETDATE(),@IDUserInfo,@IDFundTransactionParameter,0)          
              end
         end
        close @curFundCorrespondencePreference;
        deallocate @curFundCorrespondencePreference;
    --      
        end

    close @curContentManagementRights;
    deallocate @curContentManagementRights;

Ответы [ 2 ]

1 голос
/ 04 марта 2011

Сэр или мадам, вы очень хорошо справились, отказавшись ждать, пока сценарий завершит свою работу.При наличии двух курсоров ни один не прокручивается за пределы первого ряда.Сценарий действительно будет длиться вечно.(Ну, во всяком случае, до тех пор, пока система может продолжать работать.)

Вы действительно должны поместить в каждый цикл (как правило, непосредственно перед end цикла) их ассоциативные fetch from... инструкции,идентичны тем, что перед каждым циклом.

1 голос
/ 04 марта 2011

Не думаю, что многие будут читать этот очень длинный запрос.логика избыточна.

например, если (выберите количество (что-то) = 0) вы можете заменить предложением с наличием и исключить дополнительное использование вложенного курсора.

приведенный ниже код является лишь ориентировочным.я не ставил 'group by' до того, как в коде было предложение.надеюсь, это поможет.

Мой совет: SQL сделан для манипулирования данными.не отдельные объекты манипулируют как программирование ООП.Я говорю это, потому что вы пытаетесь использовать курсор для обработки каждой строки, например, в стиле программирования ООП.цикл для работы в каждой строке.но SQL намерены работать на несколько строк одновременно.попробуй использовать агрегат, случай когда вместо

   declare @IDFundInfo char(30)
    declare @IDCompany char(30)
    declare @IDFundTransactionParameter char(30)
    declare @IDContentManagement char(30)
    declare @IDUserInfo char(30)
    declare @ID char(30)

    declare @curContentManagementRights cursor
    set @curContentManagementRights = cursor fast_forward for
    --first select distinct records from ContentManagementRights for IDFundInfo, IDCompany,IDFundTransactionParameter and IDContentManagement where
    --bFundLevelAccess == 0
    SELECT distinct
       ContentManagementRights.IDFundInfo, 
       ContentManagementRights.IDCompany, 
       ContentManagementRights.IDFundTransactionParameter, 
       ContentManagementRights.IDContentManagement
    FROM ContentManagementRights 
    WHERE     
       (ContentManagementRights.bFundLevelAccess = 0)
    ORDER BY 
       idfundinfo, idcompany,idfundtransactionparameter, idcontentmanagement

    open @curContentManagementRights;
    fetch from @curContentManagementRights into @IDFundInfo, @IDCompany,@IDFundTransactionParameter,@IDContentManagement

    WHKLE @@fetch_status = 0
    BEGIN
        --get all IDContactInfo for the chosen fund, partnerid,fundtranactionparameterid from fundcorrespondencepreference table + make sure that at least one correspTO parameter

     INSERT INTO ContentManagementRights (IDContentManagementRights,IDContentManagement,IDFundInfo,IDCompany,sCreatedBy,dtCreatedDate,sUpdatedBy,dtUpdatedDate,IDUserInfo,IDFundTransactionParameter,bFundLevelAccess)
         SELECT     
             @ID,@IDContentManagement,@IDFundInfo,@IDCompany,'admin',GETDATE(),'admin',GETDATE(),UserInfo.IDUserInfo,@IDFundTransactionParameter,0
         FROM         
             FundCorrespondencePreference 
         INNER JOIN
             FundTransactionParameter ON FundCorrespondencePreference.IDFundTransactionParameter = FundTransactionParameter.IDFundTransactionParameter 
         INNER JOIN
             ContactInfo ON FundCorrespondencePreference.IDContactInfo = ContactInfo.IDContactInfo 
         INNER JOIN
             UserInfo ON ContactInfo.IDContactInfo = UserInfo.IDContactInfo 
         INNER JOIN
             UserGroupInfo ON UserInfo.IDUserInfo = UserGroupInfo.IDUserInfo 
         INNER JOIN
             GroupInfo ON UserGroupInfo.IDGroupInfo = GroupInfo.IDGroupInfo
         WHERE     
            (FundTransactionParameter.IDFundInfo = @IDFundInfo) 
            AND (FundCorrespondencePreference.IDCompany = @IDCompany) 
            AND (FundCorrespondencePreference.IDFundTransactionParameter = @IDFundTransactionParameter) 
            AND (FundCorrespondencePreference.bEmail = 1) 
            AND (GroupInfo.sName = N'Xtranet Partner Group') 
            OR (FundCorrespondencePreference.bFax = 1) 
            OR (FundCorrespondencePreference.bLetterTo = 1) 
            OR (FundCorrespondencePreference.bLetterCc = 1) 
            OR (FundCorrespondencePreference.bEmailCc = 1) 
            OR (FundCorrespondencePreference.bFaxCc = 1)

    having count(IDContentManagementRights) = 0

        end

    close @curContentManagementRights;
    deallocate @curContentManagementRights;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...