Как работает функция moveNext / moveFirst / и т.д. в Access 2007? - PullRequest
1 голос
/ 27 апреля 2010

Я не эксперт по Access, но я эксперт по SQL. Я унаследовал интерфейс Access, ссылающийся на базу данных SQL 2005, которая работала нормально около 5000 записей, но с треском проваливалась для записей 800k ...

За кулисами в профилировщике SQL и диспетчере активности я вижу какой-то запрос Access, например:

ВЫБЕРИТЕ "MS1". "Id" ИЗ "dbo". "Customer" "MS1" ЗАКАЗАТЬ "MS1". "Id"

Префикс MS не указан ни в одном коде доступа, который я вижу. Я с подозрением отношусь к встроенному коду доступа Access:

DoCmd.GoToRecord , , acNext

GoToRecord имеет константу AcRecord, которая включает такие вещи, как acFirst, acLast, acNext, acPrevious и acGoTo.

Что означает в контексте базы данных переход к «следующей» записи? Эта конкретная таблица использует столбец идентификаторов в качестве PK, поэтому он внутренне захватывает все идентификаторы и затем перемещается к тому, который является следующим по величине ???

Если так, как это будет работать, если таблица состоит из трех различных полей для ПК?

Или я не на том пути, и что-то еще в Access вызывает это утверждение? К сожалению, я вижу тонну готовых высказываний в профилировщике.

спасибо!

Ответы [ 2 ]

2 голосов
/ 27 апреля 2010

Вы должны различать автоматизацию объектов Access и работу с наборами записей в коде.

В форме эта команда имеет значение:

  DoCmd.GoToRecord , , acNext

Это неспецифично, и это не предсказуемо, к какой записи он пойдет, если вы не знаете порядок расположения базового набора записей в форме и начальной записи. Он перемещает вас по набору записей, хранящемуся в буфере редактирования формы (который загружается в событие OnOpen формы). Команда будет использоваться, например, в коде, стоящем за командной кнопкой, цель которой - перемещаться по записям, загруженным в форму, в которой в данный момент находится фокус. Я бы никогда не пропустил необязательные аргументы, если бы использовал эту команду (я почти никогда не буду). Вместо этого я бы определил конкретную форму, к которой хотел бы применить:

  DoCmd.GoToRecord acForm, "MyForm", acNext

При обходе набора записей DAO .MoveNext также не имеет предопределенного значения, кроме случаев, когда вы знаете порядок и начальную запись. Когда вы просматриваете набор записей (то, что вы не должны делать очень часто, так как это довольно неэффективно; но это зависит от задачи, которую вам нужно выполнить) и вам нужно нажать на каждую запись, вы непременно вызовете .MoveNext как часть вашего цикл:

  With rs
    .MoveFirst ' technically not required, as it's the default starting point
    Do Until .EOF
      [do something]
      .MoveNext     
    Loop
  End With

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

В ответ на ваш конкретный вопрос:

Что это значит в базе данных контекст, чтобы перейти к «следующей» записи? Эта конкретная таблица использует идентификатор колонка как ПК, так и внутренне захватывая все идентификаторы и затем двигаясь тому, кто следующий по величине ???

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

Теперь в комментарии вы говорите, что форма привязана ко всей таблице. Это ужасный дизайн, независимо от того, хранятся ли ваши данные в файле данных Jet / ACE или в базе данных сервера, такой как SQL Server. Единственная причина, по которой Access может сойти с рук, заключается в том, что он и Jet довольно эффективно извлекают данные из источника данных.

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

Что касается того, какие типы курсоров используются, вам не стоит об этом беспокоиться. По умолчанию формы доступа используют то, что Access / Jet / ACE называет набором данных. Каждая форма имеет свойство RecordsetType, и для нее установлено значение dynaset по умолчанию (прочитайте файл справки о значении различных типов наборов записей). Если вам нужен больший контроль над этим, вы можете (но, вероятно, не должны) создавать свои наборы записей в коде и назначать их свойству .Recordset формы. Это полезно в некоторых случаях, например, когда вы хотите связать форму с отключенным набором записей, но точка доступа использует свои возможности для работы со связанными данными. Назначение ваших собственных наборов записей по-прежнему дает вам связанные элементы управления и события формы, но требует больше работы, чем обычно требуется.

В основном измените свои формы, чтобы загрузить только подмножество записей, с которыми пользователь должен работать (это может быть одна запись за раз), а затем позвольте всему остальному быть выполненным с поведением по умолчанию Access. Если что-то вызывает узкое место, устраните это и замените поведение по умолчанию на что-то более эффективное.

Другими словами, избегайте преждевременной оптимизации - пусть Access будет Access.

И не беспокойтесь о том, что Access делает за кулисами, если / пока Access не сделает что-то неуместное.

2 голосов
/ 27 апреля 2010

First буквально первая строка в наборе записей. В общем, Access обращается к данным через эквивалент курсоров. Итак, Next и Previous перемещаются вперед и назад в наборе записей по одной строке за раз, как вы можете с помощью курсоров SQL Server. Будьте осторожны с зависимостью от последовательности строк без оператора ORDER BY в конструкции Recordset. Хотя Access - это ISAM, вы не должны полагаться на строки, поступающие в каком-либо определенном порядке. В зависимости от типа курсора, Access не будет тянуть всю таблицу вниз, но, как правило, будет запрашивать одну запись за раз. Тем не менее, я видел, как Access вытягивал целые таблицы по любой причине.

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