Как я могу заставить MS-Access выбрать другой / правильный план выполнения для моего запроса

У меня проблема с относительно простым запросом и планом выполнения, выбранным Access для него.

запрос имеет такую ​​форму

SELECT somethings
FROM A INNER JOIN (B INNER JOIN (C INNER JOIN D ON ...) ON ...) ON ...
WHERE A.primaryKey= 1 AND D.d = 2;

C и D имеют относительно немного строк. A и B содержат несколько тысяч строк.

Запрос, который возвращает 2 строки (не уверен, уместно ли это), очень медленный.Он работает за 17 секунд. Если я удалю часть AND D.d = 2 из предложения where, запрос теперь возвращает 4 строки и выполняется мгновенно.

Насколько я понимаю, механизм JET может мгновенно запустить запрос без фильтра на D.d, а затем мгновенно выполнить указанный фильтр (только 4 строки для фильтрации). Поэтому выполнение запроса с фильтром D.d = 2 не должно занимать слишком много времени.

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

Поскольку мне не удалось запустить запрос, как я хотел, я использовал штуку JETSHOWPLAN, чтобы Access выводил его план выполнения. Вот что я обнаружил:

Для быстрого запроса (без Dd = 2 ) первым шагом плана запроса является применение фильтра A.primaryKey = 1 на столе А. В результате получается набор данных из 1 строки из более чем 30000. Тогда кажется, что соединения выполняются от A до D с использованием индекса с набором данных, который никогда не превышает 4 строк.

Кажется, что медленный запрос выполняется в обратном порядке. Сначала соединяются D и C, затем проверяется D.d = 2 . После этого выполняются соединения от C до A. Таким образом объем данных, которые необходимо соединить от D к C, от C к B и от B к A, будет намного больше. Когда все операции JOIN выполнены и до выполнения A.primaryKey = 1 , набор данных будет содержать 120 КБ строк.

Есть ли способ принудительно составить правильный план запроса в Access?

Надеюсь, я был ясен. Сообщите мне, следует ли опубликовать планы запросов. Я не сделал этого, потому что они довольно большие.

Заранее спасибо,

mp

5
задан Mathieu Pagé 27 January 2012 в 17:14
поделиться