Выберите оптимизацию в Access - PullRequest
0 голосов
/ 08 декабря 2010

У меня серьезные проблемы, у меня огромный тонкий запрос, выполнение которого занимает огромное время.На самом деле это замораживает Access, и иногда мне приходится убивать его, запрос выглядит так:

SELECT
    ITEM.*,
    ERA.*,
    ORDR.*,
ITEM.COnTY1,
(SELECT TOP 1 New FROM MAPPING WHERE Old = ITEM.COnTY1) AS NewConTy1,
ITEM.COnValue1,
(SELECT TOP 1 KBETR FROM GEN_KUMV WHERE KNUMV = ERA.DOCCOND AND KSCHL = (SELECT TOP 1     New FROM MAPPING WHERE Old = ITEM.COnTY1)) AS NewCOnValue1
--... etc: this continues until ConTy40

FROM
GEN_ITEMS AS ITEM,
GEN_ORDERS AS ORDR,
GEN_ERASALES AS ERA

WHERE
ORDR.ORDER_NUM = ITEM.ORDER_NUM AND  -- link between ITEM and ORDR
ERA.concat = ITEM.concat -- link between ERA and ITEM

Я не буду предоставлять вам схему таблиц, так как запрос работает, я хотел бы знать, есть лиспособ добавить NewConTy1 и NewConValue1, используя другой метод, чтобы сделать его более эффективным.Дело в том, что поля Con * имеют размеры от 1 до 40, поэтому я должен выровнять их вдоль (NewConTy1 рядом с ConTy1 с NewConValue1 рядом с новым ConValue2 ... и т. Д. До 40).ConTy # и ConTyValue # в ITEMS (каждый в поле) NewConty # и NewConValue # в ERA (каждый в записи )

Я действительно надеюсь, что моего объяснения достаточно, чтобы выяснитьмоя проблема, с нетерпением жду ваших сообщений, ребята

РЕДАКТИРОВАТЬ:

Игнорировать ТОП-1 в SELECTS, это потому, что текущие дампы данных, которые я имею, не точны, они будут удалены позже

РЕДАКТИРОВАТЬ 2:

Еще одна вещь, мой запрос возвращает до 230 полей также LOL

Спасибо Милуд

Ответы [ 2 ]

3 голосов
/ 08 декабря 2010

Рассматривали ли вы запрос объединения для нормализации элементов?

SELECT "ConTy1" As CTName, Conty1 As CTVal, 
       "ConTyValue1" As CTVName,  ConTyValue1" As CTVVal
       FROM ITEMS 
UNION ALL 
SELECT "ConTy2" As CTName, Conty2 As CTVal, 
       "ConTyValue2" As CTVName,  ConTyValue2" As CTVVal
       FROM ITEMS
<...>
UNION ALL 
SELECT "ConTy40" As CTName, Conty40 As CTVal, 
       "ConTyValue40" As CTVName,  ConTyValue40" As CTVVal
       FROM ITEMS

Это может быть либо отдельный запрос, который ссылается на ваш основной запрос, либо подзапрос вашего основного запроса, если это более удобно. Затем должно быть достаточно просто нарисовать связь с NewConty # и NewConValue # в ERA.

0 голосов
/ 08 декабря 2010

Ответ Рему дает то, что вы хотите - существенно другой подход. Прошло много времени с тех пор, как я вмешивался в оптимизацию запросов MS Access и забыл о деталях его планировщика, но вы можете попробовать тривиальное предложение, чтобы реально сделать ваш

WHERE conditions

в

INNER JOIN ON conditions

Вы запускаете 40-ю коррелированные подзапросы, поэтому вышеприведенное, вероятно, не поможет (опять-таки ответ Рему использует существенно другой подход, и вы можете увидеть реальные улучшения там), но сообщите нам об этом, поскольку тестирование тривиально.

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

Например, ваш первый подзапрос коррелируется с ITEM.COnTY1, ваш второй - с ERA.DOCCOND и ITEM.ConTY1.

Если вы классифицируете свои подзапросы в соответствии с коррелированными ключами, то вы можете сохранить их как запросы (или материализовать их как запросы к таблицам) и присоединиться к ним (или к вновь созданным таблицам), что должно выполняться намного быстрее (и в в случае make таблиц будет работать намного быстрее, за счет материализации - поэтому вам придется выполнить некоторые запросы перед получением последних данных - это может быть заключено в макрос или функцию / подпрограмму VBA).

В противном случае (например, если вы регулярно выполняете вышеуказанный запрос как часть обычного бизнес-сценария) - перепроектируйте свою БД.

...