Access 2002 - несколько уровней вложенных внутренних объединений в одной таблице (по сравнению с обычными внутренними объединениями)? - PullRequest
1 голос
/ 20 сентября 2011

Я унаследовал плохо спроектированную базу данных Access 2002.Я пытаюсь устранить неполадки в нескольких запросах, и один из них, в частности, заставил меня почесать голову.Он вкладывает несколько соединений в одну и ту же таблицу ... каждое соединение вкладывается в предыдущее объединение, а не просто присоединяется к одной и той же таблице несколько раз.Я, честно говоря, даже не могу точно сказать, почему этот запрос работает - я никогда не видел, чтобы объединение создавалось таким образом ... Может кто-нибудь прокомментировать влияние этих внутренних объединений (с точки зрения производительности?), И я увижу, как-нет их?

Пример:

--Detals cut
FROM tempMapIDs INNER JOIN 
(BenefitMapRiders AS RxDeduct INNER JOIN 
(BenefitMapRiders AS SubAbuse INNER JOIN 
(BenefitMapRiders AS Infertility INNER JOIN 
(BenefitMapRiders AS Dental INNER JOIN 
(BenefitMapRiders AS Chiro INNER JOIN 
(BenefitMapRiders AS Vision INNER JOIN 
(BenefitMapRiders AS Drug INNER JOIN qryOptionsMap ON Drug.NewRiderOption = qryOptionsMap.Drug) 
ON Vision.NewRiderOption = qryOptionsMap.Vision) 
ON Chiro.NewRiderOption = qryOptionsMap.Chiro) 
ON Dental.NewRiderOption = qryOptionsMap.Dental) 
ON Infertility.NewRiderOption = qryOptionsMap.Infertility) 
ON SubAbuse.NewRiderOption = qryOptionsMap.SubAbuse) 
ON RxDeduct.NewRiderOption = qryOptionsMap.RxDeduct) 

ON (tempMapIDs.NewDate = qryOptionsMap.RenewalDate) 
    AND (tempMapIDs.NewPlanOption = qryOptionsMap.PlanOption) 
    AND (tempMapIDs.RxDeduct = RxDeduct.OldRiderOption) 
    AND (tempMapIDs.SubAbuse = SubAbuse.OldRiderOption) 
    AND (tempMapIDs.Infertility = Infertility.OldRiderOption) 
    AND (tempMapIDs.Chiro = Chiro.OldRiderOption) 
    AND (tempMapIDs.Vision = Vision.OldRiderOption) 
    AND (tempMapIDs.Dental = Dental.OldRiderOption) 
    AND (tempMapIDs.Drug = Drug.OldRiderOption) 
    AND (tempMapIDs.MapID = RxDeduct.MapID) 
    AND (tempMapIDs.MapID = SubAbuse.MapID) 
    AND (tempMapIDs.MapID = Infertility.MapID) 
    AND (tempMapIDs.MapID = Chiro.MapID) 
    AND (tempMapIDs.MapID = Vision.MapID) 
    AND (tempMapIDs.MapID = Dental.MapID) 
    AND (tempMapIDs.MapID = Drug.MapID)
) 

Ответы [ 3 ]

3 голосов
/ 20 сентября 2011

Именно таким способом Access стремится писать запросы, когда вы используете визуальный конструктор запросов для их создания. Он не должен работать хуже, чем тот же синтаксис, к которому вы привыкли.

Создайте новый запрос с двумя или тремя объединениями, используя визуальный конструктор, и вы увидите тот же синтаксис.

2 голосов
/ 21 сентября 2011

Мне кажется, я знаю, откуда ты.Я бы предпочел писать одинаковые объединения таким образом, чтобы держать пункты ON рядом с предложениями JOIN для простоты чтения и, следовательно, обслуживания, например:

FROM 
     tempMapIDs 

     INNER JOIN qryOptionsMap 
        ON tempMapIDs.NewDate = qryOptionsMap.RenewalDate
           AND tempMapIDs.NewPlanOption = qryOptionsMap.PlanOption

     INNER JOIN BenefitMapRiders AS RxDeduct 
        ON tempMapIDs.MapID = RxDeduct.MapID
           AND tempMapIDs.RxDeduct = RxDeduct.OldRiderOption
           AND RxDeduct.NewRiderOption = qryOptionsMap.RxDeduct

     INNER JOIN BenefitMapRiders AS SubAbuse 
        ON tempMapIDs.MapID = SubAbuse.MapID
           AND tempMapIDs.SubAbuse = SubAbuse.OldRiderOption
           AND SubAbuse.NewRiderOption = qryOptionsMap.SubAbuse

     INNER JOIN BenefitMapRiders AS Infertility 
        ON tempMapIDs.MapID = Infertility.MapID
           AND tempMapIDs.Infertility = Infertility.OldRiderOption
           AND Infertility.NewRiderOption = qryOptionsMap.Infertility

     INNER JOIN BenefitMapRiders AS Dental
        ON tempMapIDs.MapID = Dental.MapID
           AND tempMapIDs.Dental = Dental.OldRiderOption
           AND Dental.NewRiderOption = qryOptionsMap.Dental

     INNER JOIN BenefitMapRiders AS Chiro 
        ON tempMapIDs.MapID = Chiro.MapID
           AND tempMapIDs.Chiro = Chiro.OldRiderOption 
           AND Chiro.NewRiderOption = qryOptionsMap.Chiro     

     INNER JOIN BenefitMapRiders AS Vision 
        ON tempMapIDs.MapID = Vision.MapID
           AND tempMapIDs.Vision = Vision.OldRiderOption
           AND Vision.NewRiderOption = qryOptionsMap.Vision

     INNER JOIN BenefitMapRiders AS Drug 
        ON tempMapIDs.MapID = Drug.MapID
           AND tempMapIDs.Drug = Drug.OldRiderOption
           AND Drug.NewRiderOption = qryOptionsMap.Drug

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

Однако приведенный выше код не является допустимым синтаксисом Access (ACE, Jet и т. д.) (к сожалению, он не поддерживает SQLСтандарт).Скорее, это заставляет вас помещать каждое соединение в скобки.Лично я бы оставил объединения в приведенной выше структуре и добавил бы скобки таким образом, чтобы они были как можно более незаметными, например

FROM (((((((
     tempMapIDs 

     INNER JOIN qryOptionsMap 
        ON tempMapIDs.NewDate = qryOptionsMap.RenewalDate
           AND tempMapIDs.NewPlanOption = qryOptionsMap.PlanOption
     )
     INNER JOIN BenefitMapRiders AS RxDeduct 
        ON tempMapIDs.MapID = RxDeduct.MapID
           AND tempMapIDs.RxDeduct = RxDeduct.OldRiderOption
           AND RxDeduct.NewRiderOption = qryOptionsMap.RxDeduct
     )
     INNER JOIN BenefitMapRiders AS SubAbuse 
        ON tempMapIDs.MapID = SubAbuse.MapID
           AND tempMapIDs.SubAbuse = SubAbuse.OldRiderOption
           AND SubAbuse.NewRiderOption = qryOptionsMap.SubAbuse
     )
     INNER JOIN BenefitMapRiders AS Infertility 
        ON tempMapIDs.MapID = Infertility.MapID
           AND tempMapIDs.Infertility = Infertility.OldRiderOption
           AND Infertility.NewRiderOption = qryOptionsMap.Infertility
     )
     INNER JOIN BenefitMapRiders AS Dental
        ON tempMapIDs.MapID = Dental.MapID
           AND tempMapIDs.Dental = Dental.OldRiderOption
           AND Dental.NewRiderOption = qryOptionsMap.Dental
     )
     INNER JOIN BenefitMapRiders AS Chiro 
        ON tempMapIDs.MapID = Chiro.MapID
           AND tempMapIDs.Chiro = Chiro.OldRiderOption 
           AND Chiro.NewRiderOption = qryOptionsMap.Chiro     
     )
     INNER JOIN BenefitMapRiders AS Vision 
        ON tempMapIDs.MapID = Vision.MapID
           AND tempMapIDs.Vision = Vision.OldRiderOption
           AND Vision.NewRiderOption = qryOptionsMap.Vision
     )
     INNER JOIN BenefitMapRiders AS Drug 
        ON tempMapIDs.MapID = Drug.MapID
           AND tempMapIDs.Drug = Drug.OldRiderOption
           AND Drug.NewRiderOption = qryOptionsMap.Drug

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

0 голосов
/ 20 сентября 2011

Если запрос работает плохо, вы должны убедиться, что поля, используемые в объединении, проиндексированы.

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