Как MS Access объединяет связанные таблицы (связанные с той же базой данных SQL-сервера)?

У меня есть база данных MS Access со связанными таблицами, когда каждая таблица связана с таблицей в той же базе данных SQL Server. У меня есть запрос внутри Access, который объединяет две таблицы (в частности, я обновляю таблицу на основе другой, используя соединение).

Вопрос в том, «загружает» ли Access все данные таблицы перед выполнением соединения? Или это умно и присоединяется к нему на SQL Server?

Запрос:

UPDATE TBL_INVOICE_CHARGES INNER JOIN TBL_ANI 
ON  (TBL_INVOICE_CHARGES.CH_CUST_ID = TBL_ANI.ANI_CUST_ID) 
AND (TBL_INVOICE_CHARGES.CH_ANI = TBL_ANI.ANI_NZ_ANI) 
SET TBL_INVOICE_CHARGES.ANI_NOTES = TBL_ANI.ANI_NOTES;
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
4 082
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

По словам Альберта Д. Каллала (Access MVP), Access не извлекает целые таблицы, за исключением сложных представлений, где все может запутаться. Однако лучше всего использовать представления на сервере и ссылку на представление или использовать сквозные запросы.

Дополнительная информация: Как создать сквозной запрос SQL в Access

Скорее всего, Jet передаст все это SQL Server, который выполнит индексное соединение, а затем выполнит обновления. Другими словами, для простого запроса, подобного вашему примеру, все выполняется на сервере, и ни один байт не протягивается по сети для локальной обработки.

Довольно легко заставить Jet тянуть за собой весь стол. Самый простой способ - поместить выражение Access в предложение WHERE. Вот пример, который может вызвать это:

   WHERE Format(MyDate,"YYYY") = 2008

Придется вытащить всю таблицу, чтобы Access мог запускать функцию Format () для всех дат в вашей таблице. Кроме того, он не сможет использовать какие-либо индексы и, следовательно, будет работать очень медленно. С серверной частью Jet тоже было бы медленно, просто потому, что это так неэффективно. Правильный способ написать это предложение WHERE:

   WHERE MyDate Between #1/1/2008# And #12/31/2008#

Если вы напишете это в сохраненном запросе доступа, он будет передан на SQL Server для обработки (и ODBC отправит соответствующие разделители, если ваш внутренний механизм db использует отличные от того, что использует Jet SQL).

Но если вы этого не делаете, вы вряд ли столкнетесь с проблемой передачи слишком большого количества данных по сети. На самом деле Jet довольно умен и отлично справляется с отправкой как можно большего количества запросов по сети для обработки. Например, если вы вызываете функции Access в своем операторе SELECT, базовый выбор без функций Access будет отправлен на сервер, а затем функции будут выполняться в Access для набора результатов. Для этого запроса доступа:

   SELECT Format(MyDate,"MM-DD")
   FROM MyTable
   WHERE MyDate Between #1/1/2008# And #12/31/2008#

Jet отправит это на сервер:

   SELECT MyDate
   FROM MyTable
   WHERE MyDate Between #1/1/2008# And #12/31/2008#

Как только Jet получит от сервера только строки, соответствующие критериям, он только тогда отформатирует поле даты с помощью функции Access Format (). Это также работает с СОЕДИНЕНИЯМИ, особенно с соединениями по индексированным полям (хотя соединения с неиндексированными полями, вероятно, также будут переданы серверу).

Иногда Jet действительно ошибается и оказывается невероятно неэффективным. В этих случаях вы можете настроить представления и хранимые процедуры на сервере и использовать сквозные запросы, чтобы избежать ошибочных предположений Jet.

Ответ принят как подходящий

Я посмотрел на SQL Profiler (к сожалению, у меня нет под рукой реального журнала), и вот что я нашел:

  • он выбирает все записи из обеих таблиц
  • для каждой записи в одной таблице вызывает ОБНОВЛЕНИЕ Так что это будет медленно.

Другие вопросы по теме