foxty [оригинальная работа]
недавно изучала, как написать алгоритм подкачки с большим количеством страниц. Я разобрался с этим, и идеи заключаются в следующем:
Во-первых, в базе данных должно быть поле автоматической нумерации (ID). Затем при первом посещении вынимаем все записи, настраиваем количество записей на каждой странице PageSize, вычисляем количество страниц, а затем создаем одномерный массив PageId (PageCount) на основе количества страниц PageId(0. ) сохраняет начальные условия тестирования записи, а затем, соответствующий каждому элементу, сохраняет код границы идентификатора, соответствующий каждой странице (
1. Код границы идентификатора: если последовательность записей идентификатора записи базы данных следующая: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16.
Предполагая, что вам нужно отсортировать по идентификатору, PageSize = 5, Pagecount = 4, PageId(4)
Значения массива PageId: PageId(0) = 1, PageId(1) = 5, PageId(2) = 10, PageId(3) = 15, PageId(4) = 16.
При доступе к i-й странице выполните прямой поиск записей между [PageId(i-1), PageId(i)). Это гарантирует, что каждый раз будут извлекаться только записи PageSize.
Предположим, вам нужно отсортировать по идентификатору в обратном порядке:
Значения массива PageId: PageId(0) = 16, PageId(1) = 12, PageId(2) = 7, PageId(3) = 2, PageId(4) = 1. При обращении к i-му страница, непосредственно Найдите идентификатор, принадлежащий [ PageId(i-1) , PageId(i) )
)
Сохраните массив PageId() в Application() для облегчения доступа, чтобы Application() инициализировался только при первом обращении к пейджеру. Часть кода имеет следующий вид: (далее — новая программа)
<%
Время1 = Таймер()
Дим Конн
Set Conn = Server.CreateObject("Adodb.Connection")
Conn.open "Driver={MicroSoft Access Driver (*.mdb)};Dbq="&Server.MapPath("db.mdb")
'www.downcodes.com
Тусклая страница, PageCounts, PageId, PageList
Дим РС,Sql
Дим IsInit, я
IsInit = False 'Флаг используется для определения того, инициализировано ли приложение ("PageId").
PageList = 20 'Установить 20 фрагментов данных для отображения на каждой странице
Установите Rs = Server.CreateObject("Adodb.Recordset")
Page = Request.QueryString("Page") 'Обратите внимание, что номер страницы необходимо проверить на тип
If IsEmpty(Application("PageId")) then 'Если приложение("PageId") еще не инициализировано, сначала инициализируйте его
Response.Write("Запустить приложение!<br>")
Sql = "Выбрать * Из теста Order By Id Desc" 'Предположим, что это отсортировано в обратном порядке по идентификатору
Rs.open Sql,Conn,1,1 'Получить объект набора записей
Если нет (Rs.Eof или Rs.Bof), Тогда
Rs.PageSize = PageList 'Установить количество записей на странице
PageCounts = рупий PageCount
ReDim PageId(PageCounts) 'Переопределяем массив PageId
For i = 0 To PageCounts 'Начинаем присваивать значения массиву PageId()
Если Rs.eof, то выйти за
PageId(i) = Rs("ID")
Rs.Move(Список страниц)
Следующий
Rs.MoveLast
PageId(PageCounts) = Rs("ID")
Приложение.Lock()
Приложение("Идентификатор страницы") = Идентификатор страницы
Приложение.UnLock()
Конец, если
Rs.Закрыть
Конец, если
IdStart = Clng(Приложение("PageId")(Страница-1))
IdEnd = Clng(Приложение("PageId")(Страница))
Sql = "Выберите * из теста, где id<="&IdStart&" и id>"&IdEnd&" "
Rs.open Sql, Conn, 1,1
Пока не рупий.eof
Response.Write(rs(0)&"--"&rs(1))
Rs.MoveNext
Венд
Rs.Закрыть
Установите рупий = ничего
Конн.Закрыть
SetConn=Ничего
Для i = 1 To Ubound(Application("PageId"))
Response.Write("<a href='Test1.asp?Page="&i&"'>"&i&"</a> ")
Следующий
Время2 = Таймер()
Response.Write("<br>"&(Время2-Время1)*1000)
'Application.Contents.Remove("PageId")
%>
Традиционный код подкачки выглядит следующим образом: (далее старая программа)
<%
Время1 = Таймер()
Дим Конн
Set Conn = Server.CreateObject("Adodb.Connection")
Conn.open "Driver={MicroSoft Access Driver (*.mdb)};Dbq="&Server.MapPath("db.mdb")
Тусклая страница, PageCounts, PageList
Дим РС,Sql
Список страниц = 20
Страница = Request.QueryString("Страница")
Установите Rs = Server.CreateObject("Adodb.Recordset")
Sql = "Выбрать * из тестового заказа по идентификатору desc"
Rs.Open Sql, Conn, 1,1
Если Страница = "" Тогда Страница = 1
Если нет (Rs.eof или Rs.Bof), то
Rs.PageSize = Список страниц
PageCounts = рупий PageCount
Rs.AbsolutePage = Страница
Конец, если
Для i = 1 в PageList
Если Rs.eof, то выйти за
Response.Write(Rs(0)&"-----"&Rs(1)&"<br>")
Rs.MoveNext
следующий
Для i = 1 в PageCounts
Response.Write("<a href='Test.asp?Page="&i&"'>"&i&"</a> ")
Следующий
Время2 = Таймер()
Response.Write("<br>"&(Время2-Время1)*1000)
%>
Фактически, общая идея состоит в том, чтобы создать глобальный массив Application("PageId"), и каждый элемент сохраняет диапазон идентификаторов записи на странице. Например, Application("PageId")(0) сохраняет идентификатор. первый элемент. Затем Application("PageId")(1) сохраняет первый идентификатор следующей страницы... и так далее. Когда вам нужно получить доступ к i-й странице, просто найдите идентификатор непосредственно в [Application(). "PageId")(i- 1) , Application("i") ) Таким образом, вам нужно каждый раз искать только необходимое количество записей, вместо того, чтобы каждый раз искать все записи. Однако этот метод используется. первый доступ. Когда необходимо создать массив Application("PageId"), он работает немного медленнее. При доступе в N-й раз (N>1) скорость почти в 10 раз выше. Я использовал две вышеупомянутые программы. тест:
1. В базе данных 32 000 записей. Старой программе требуется около 500 миллисекунд для доступа к одной странице. Новая программа достигает этого времени только при первом доступе, а затем каждый раз занимает всего около 55 миллисекунд.
2. Увеличьте количество данных до 64 000 записей. Старой программе требуется около 1000 миллисекунд для доступа к одной странице. Новая программа также достигает этого уровня при первом доступе к ней. В дальнейшем оно все равно остается на уровне около 55 миллисекунд.
3. Увеличьте данные до 128 000 записей. Старой программе требуется около 1900 миллисекунд для доступа к одной странице, новой программе требуется около 2300 миллисекунд для доступа к одной странице в первый раз, а затем каждый доступ занимает всего около 70 миллисекунд.
Здесь следует отметить, что каждый раз при изменении базы данных необходимо переназначать Application("PageId").
Опыт исследования: (Прежде всего, спасибо Е Цзы (DVBBS) за ваш опыт) Старайтесь не использовать встроенная программа подкачки Rs.RecordCount очень ресурсозатратна. В свою очередь, предполагается, что Rs.PageCount... также потребляет ресурсы, а эффект от использования Rs.GetRows() также значительно улучшается.
После сравнения, скорость и эффективность листового алгоритма относительно высоки, когда количество записей относительно велико. Но оно не очень стабильное, иногда (редко) скачет примерно с 30мс до 1-200мс. После этого эффективность значительно падает до 50-80 миллисекунд, и чем позже эффективность становится ниже. Эффективность нового алгоритма в первое время относительно невысока, около 500 миллисекунд, но в дальнейшем она обычно составляет около 50 миллисекунд, а при изменении количества записей в библиотеке эта скорость остается прежней. Ничего не изменится. В следующий раз я попробую объединить Ye Ye со своим алгоритмом, но алгоритм Ye Ye действительно очень хорош и универсален. Я могу использовать его только для общения.