Программа C#, запрашивающая базу данных Access в сетевой папке, занимает больше времени, чем запрос локальной копии

У меня есть приложение C#, которое использует базу данных MS Access (файл .mdb). Я делюсь своей базой данных с пользователями сети, чтобы они могли получить доступ к базе данных с помощью моего приложения.

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

Может ли кто-нибудь дать совет о том, как уменьшить эту проблему с производительностью с базой данных Access на сетевом ресурсе?


person Ankit    schedule 13.11.2013    source источник
comment
Не используйте JET или ACE.   -  person ta.speot.is    schedule 13.11.2013


Ответы (1)


Конечно, запросы на доступ к базе данных по сети не будут такими же быстрыми, как те же запросы на доступ к базе данных на локальном жестком диске. К сожалению, разработчик довольно часто создает приложение, которое нормально работает локально, но значительно замедляется после развертывания в сети. (Это может быть справедливо для любого разработчика, а не только для тех, кто использует базы данных Access.)

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

Индексируйте соответствующим образом

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

Для иллюстрации я выполнил следующую команду для файла .accdb размером 122 МБ, содержащего одну таблицу с 421 184 строками:

cmd.CommandText =
    "SELECT COUNT(*) AS n FROM zz_sys_archive " +
    "WHERE archived Between #2013-01-01# And #2013-04-01#";

Без индекса в поле [archived] команда выполнялась 78 секунд и генерировала 107 МБ сетевого трафика.

После добавления индекса в поле [archived] эта же команда выполнялась за 0,4 секунды и генерировала 0,9 МБ сетевого трафика.

(Однако не сходите с ума и не индексируйте все, потому что посторонние индексы только замедлят операции INSERT и UPDATE.)

Запрашивайте разумно

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

cmd.CommandText =
    "SELECT COUNT(*) AS n FROM zz_sys_archive " +
    "WHERE Year(archived) = 2013";

не является sargable, что означает, что он не может использовать индекс в поле [archived] и делает таблицу сканирование с теми же результатами, что и раньше (около 80 секунд). Однако эквивалентный запрос

cmd.CommandText =
    "SELECT COUNT(*) AS n FROM zz_sys_archive " +
    "WHERE archived >= #2013-01-01# AND archived < #2014-01-01#";

потребовалось около одной секунды для выполнения.

Не читайте то, что вам не нужно

При работе с локальной базой данных часто возникает соблазн просто прочитать всю таблицу и проигнорировать то, что вам на самом деле не нужно. Доступ к базе данных по сети делает это намного более дорогим, поэтому подумайте о том, что вам на самом деле нужно, прежде чем просто "ВЫБЕРИТЕ * ИЗ ОТКУДА".

person Gord Thompson    schedule 13.11.2013