API JetPrereadKeys () выполняет синхронизацию c до уровня родительского уровня, а затем ставит в очередь asyn c IOs для всех листовых страниц, необходимых для нужных ключей / записей ... Я думаю, что ответы # 2. Если записи вашей основной таблицы (обратите внимание, что длинные значения пакета / LV хранятся в отдельном дереве) являются поверхностными или полностью кэшированными, этот JetPrereadKeys () может не помочь. Однако, если ваше основное дерево в таблице большое и глубокое, то этот API может существенно помочь ... он зависит только от формы и распространения ваших данных, которые вы получаете. Вы можете рассказать некоторые основные сведения о своей таблице, выбрасывая пространство и просматривая глубину деревьев и получая представление о страницах «Данные». Могу я предложить:
esentutl /ms Your.Db /v /fName,Depth,Internal,Data
Список имен таблиц, глубины, сколько внутренних страниц и сколько страниц данных конечного уровня. Отдельные строки будут перечислены для основного дерева записей по имени таблицы, а затем LV ниже / как «[Длинные значения]» под ним.
Также обратите внимание, что эти предварительно прочитанные ключи также не распространяются на пакетные LV. .. так что опять же, если вы сразу же прочитаете столбец LV пакета - к сожалению, вы прикрепитесь к IO.
По умолчанию ESE выделяет и управляет исключительно собственным буфером базы данных / кэшем страниц. JET_paramEnableFileCache в первую очередь предназначен для (обычно меньших) клиентских процессов, которые выходят (или, по крайней мере, JetTerm / JetDetach их БД) и перезапускают много ... так, где частный буферный кэш ESE будет потерян при каждом выходе ... но JET_paramEnableFileCache параметр, так что данные могут все еще находиться в файловом кеше, если они недавно выходили. Однако это не рекомендуется для больших БД, поскольку это приводит к двойному кешированию данных в буферном кеше ESE и в файловом кеше NTFS / ReFS. JET_paramEnableViewCache улучшает предыдущий параметр и несколько улучшает этот двойной кеширование ... но он может только сэкономить память / не двойной буфер на чистых / неизмененных буферах страниц. Для больших БД оставьте оба этих параметра выключенными / ложными. Кроме того, если вы не используете эти параметры, тогда проще протестировать «холодный перфоманс» ... просто скопируйте большой файл (100 МБ, может быть 1 или 2 ГБ) пару раз на вашем HD после того, как ваше приложение выйдет (очистить HD кеш), и ваши данные будут холодными. ; -)
Итак, теперь, когда мы упомянули о кешировании ... последнее, что я думаю, вероятно, является вашей реальной проблемой (если это не «форма ваших данных», о которой я упоминал выше) .. Откройте perfmon и найдите объекты perf «База данных» и / или «База данных ==> Экземпляры» (они предназначены для ESENT) и посмотрите, насколько велик размер вашего кэша [«Размер кэша базы данных» или «Размер кэша базы данных (МБ)». "] и посмотрите, насколько велик ваш доступный пул / [" Database Cache% Available "] ... вам, конечно, придется взять этот% и сделать математику с размером кэша вашей базы данных, чтобы получить представление ... НО, если это низкий, это может быть вашей проблемой ... это потому, что JetPrereadKeys будет использовать только уже имеющиеся буферы, поэтому вы должны иметь здоровый / достаточно большой доступный пул. Либо увеличьте JET_paramCacheSizeMin, чтобы он был больше, либо задайте JET_paramStartFlushThreshold / JET_paramStopFlushThreshold, чтобы размер доступного кеша был больше% от общего размера кеша ... обратите внимание, что они установлены пропорционально JET_paramCacheSizeMax, например, установка:
paramCacheSizeMin = 500
paramCacheSizeMax = 100000
paramStartFlush.. = 1000
paramStopFlushT.. = 2000
будет означать, что ваши пороги запуска и остановки равны 1% и 2% соответственно от вашего текущего размера кэша, каким бы он ни был. Таким образом, если кэш находится в 500 буферах (мин), 5 и 10 будут вашими порогами начала / остановки - то есть диапазон, в котором будет находиться ваш доступный пул, если позже он увеличится до 10000 буферов, то ваш доступный пул будет в диапазоне от 100 до 200 буферы. В любом случае, вы хотите, чтобы эти числа были достаточно хорошим диапазоном, чтобы у вас было достаточно буферов для всех конечных страниц, которые могут понадобиться JetPrereadKeys.
Я не объяснил каждый термин в этом письме, потому что вы выглядели довольно продвинутыми выше - говорящие внутренние узлы B-дерева и тому подобное ... но если что-то не понятно, просто спросите, и я все проясню.
Спасибо,
Бретт Ширли [MSFT]
Extensible Storage Engine Developer
Эта публикация предоставляется "КАК ЕСТЬ" без каких-либо гарантий и не дает никаких прав.
PS - Последнее, с чем вам может понравиться играть: JetGetThreadStats / JET_THREADSTATS, он сообщает вам некоторые из наших внутренних операций, которые мы делаем в API. Вы в основном читаете значения до и после и JET API и вычитаете их, чтобы получить количество операций для этого JET API. Итак, вы увидите cPagePreread там ... это будет хороший способ узнать, отправляет ли JetPrereadKeys с Asyn c IOs, что должно помочь перфекту. Обратите внимание, что в старых ОС, к сожалению, был сломан конкретный счетчик, но я не помню, когда он был сломан и исправлен ... win7 - win8, win8 - win8.1. Если у вас Win10, то никаких проблем к тому времени это точно не решило. ;-) А также cPageRead синхронизирует c чтение страниц (что может go для внутренних узлов) ... Я думаю, вы найдете их очень поучительными для затрат на различные JET API.