"Min in Select Statement" или DMin (). Какой из них предпочтительнее? - PullRequest
1 голос
/ 23 марта 2012

Мне нужно было найти минимальный доход по таблице tbl_Revenue.Я нашел два способа сделать это:

Метод 1

Dim MinRevenueSQL As String
Dim rsMinRev As DAO.Recordset
MinRevenueSQL = "SELECT Min(tbl_Revenue.Revenue_Value)As MinRevenue FROM tbl_Revenue WHERE (((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'));"
Set rsMinRev = CurrentDb.OpenRecordset(MinRevenueSQL)
MinRev = rsMinRev!MinRevenue

Метод 2

MinRev2 = DMin("Revenue_Value", "tbl_Revenue", "(((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'))")

У меня есть следующие вопросы:

  1. какой из них является вычислительно более эффективным?Много ли различий в вычислительной эффективности, если вместо таблицы tbl_Revenue выбран отбор статистики с использованием объединений?
  2. Есть ли проблема с точностью накопления DMin?(Под точностью я подразумеваю, есть ли какие-либо лазейки, о которых мне нужно знать перед использованием DMin.)

Ответы [ 2 ]

2 голосов
/ 23 марта 2012

Я подозреваю, что ответ может варьироваться в зависимости от вашей ситуации.
В ситуации с одним пользователем метод тестирования @ transistor1 даст вам хороший ответ для изолированного поиска.

Но если для базы данных, общей для сети, ЕСЛИ вы уже Set db = CurrentDb, то метод SELECT должен быть более быстрым, поскольку он не требует открытия второго соединения сдБ, что медленно.

Точно так же, более эффективно Set db = CurrentDb и повторное использование этого дБ везде.
В ситуациях, когда я хочу убедиться, что у меня лучшая скорость, я использую Public db as DAO.Database при открытии приложения,Затем в каждом модуле, где это требуется, я использую
If db is Nothing Then set db = CurrentDb.

1 голос
/ 23 марта 2012

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

Если для вас важна производительность за тысячи итераций, я бы написал что-то вроде следующего:

Sub runDMin()
    x = Timer

    For i = 1 To 10000
        MinRev2 = DMin("Revenue_Value", "tbl_Revenue", "(((tbl_Revenue.Division_ID)=20) AND ((tbl_Revenue.Period_Type)='Annual'))")
    Next

    Debug.Print "Total runtime seconds:" & Timer - x
End Sub

Затем выполните то же самое для запроса DAO, заменив часть MinRev2. Запустите их оба несколько раз и возьмите в среднем. Старайтесь изо всех сил имитировать условия, при которых он будет работать; например, если вы будете изменять параметры в каждом запросе, сделайте то же самое, потому что это, скорее всего, повлияет на производительность обоих методов. Я сделал нечто подобное с DAO и ADO в Access и с удивлением обнаружил, что в моих условиях DAO работал быстрее (это было несколько лет назад, поэтому, возможно, с тех пор все изменилось).

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

Совет: хотя вы можете использовать функцию DMin, чтобы найти минимальное значение из поля в чужой таблице может быть более эффективно создать запрос, содержащий поля, которые вам нужны из обеих таблиц, и основывайте свою форму или отчет по этому запросу.

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

Я склонен полагать (возможно, ошибочно, потому что у меня нет никаких доказательств), что функции домена (DMin, DMax и т. Д.) Работают медленнее, чем использование SQL. Возможно, если вы запустите приведенный выше код, сообщите нам, как это получается.

Если вы правильно напишите вызов DMin, проблем с точностью, о которых я знаю, нет. Вы слышали, что были? По сути, звонок должен быть: DMin("<Field Name>", "<Table Name>", "<Where Clause>")

Удачи!

...