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

У меня есть база данных 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;

Ответы [ 3 ]

2 голосов
/ 08 декабря 2008

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

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

   WHERE Format(MyDate,"YYYY") = 2008

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

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

Если вы напишите это в сохраненном запросе Access, он будет передан на SQL Server для обработки (и ODBC отправит соответствующие разделители, если ваш внутренний движок БД использует отличные от тех, которые использует 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.

2 голосов
/ 08 декабря 2008

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

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

0 голосов
/ 11 декабря 2008

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

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