foxty [trabalho original]
recentemente estudou como escrever um algoritmo de paginação alta e pequena. Eu resolvi isso e as ideias são as seguintes:
Primeiro, é necessário que haja um campo de numeração automática (ID) no banco de dados. Em seguida, na primeira visita, retire todos os registros, personalize o número de registros em cada página PageSize, calcule o número de páginas e, em seguida, crie um array unidimensional PageId (PageCount) com base no número de páginas PageId (0. ) salva as condições de teste iniciais do registro e, em seguida, correspondente a cada elemento, salva o código de limite de ID correspondente a cada página (
1. Código de limite de ID: se a sequência de registro de ID do registro do banco de dados for a seguinte: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
Supondo que você precise classificar por ID, PageSize = 5, Pagecount = 4, PageId(4)
Os valores da matriz PageId são PageId(0) = 1, PageId(1) = 5, PageId(2) = 10, PageId(3) = 15, PageId(4) = 16
Ao acessar a i-ésima página, pesquise diretamente os registros entre [PageId(i-1), PageId(i)). Isso garante que apenas os registros PageSize sejam recuperados a cada vez.
Suponha que você precise classificar por ID na ordem inversa,
Os valores do array PageId são PageId(0) = 16, PageId(1) = 12, PageId(2) = 7, PageId(3) = 2, PageId(4) = 1. Ao acessar o i-ésimo página, encontre diretamente o ID pertencente a [ PageId(i-1) , PageId(i) )
)
Salve o array PageId() em Application() para facilitar o acesso, para que Application() seja inicializado apenas na primeira vez que o pager for acessado. A parte do código é a seguinte: (doravante denominado novo programa)
<%
Tempo1 = Temporizador()
Dim Conexão
Definir Conexão = Server.CreateObject("Adodb.Connection")
Conn.open "Driver={MicroSoft Access Driver (*.mdb)};Dbq="&Server.MapPath("db.mdb")
'www.downcodes.com
Dim Page,PageCounts,PageId,PageList
Dim Rs,Sql
Dim IsInit,i
IsInit = False 'O sinalizador é usado para determinar se o aplicativo ("PageId") foi inicializado
PageList = 20 'Defina 20 dados a serem exibidos em cada página
Definir Rs = Server.CreateObject("Adodb.Recordset")
Page = Request.QueryString("Page") 'Observe que o número da página precisa ser verificado quanto ao tipo
If IsEmpty(Application("PageId")) Then 'Se Application("PageId") ainda não foi inicializado, inicialize-o primeiro
Response.Write("Iniciar aplicativo!<br>")
Sql = "Select * From test Order By Id Desc" 'Suponha que isso seja classificado em ordem inversa por ID
Rs.open Sql,Conn,1,1 'Obtém o objeto recordset
Se não (Rs.Eof ou Rs.Bof), então
Rs.PageSize = PageList 'Define o número de registros por página
Contagens de páginas = Rs.Contagem de páginas
ReDim PageId(PageCounts) 'Redefine o array PageId
For i = 0 To PageCounts 'Começa a atribuir valores ao array PageId()
Se Rs.eof, então saia para
PageId(i) = Rs("ID")
Rs.Move (Lista de Páginas)
Próximo
Rs.MoveLast
PageId(PageCounts) = Rs("ID")
Aplicativo.Lock()
Aplicativo("PageId") = PageId
Aplicativo.UnLock()
Terminar se
Rs.Fechar
Terminar se
IdStart = Clng(Application("PageId")(Página-1))
IdEnd = Clng(Application("PageId")(Página))
Sql = "Selecione * do teste onde id<="&IdStart&" e id>"&IdEnd&" "
Rs.open Sql,Conn,1,1
Embora não seja Rs.eof
Resposta.Write(rs(0)&"--"&rs(1))
Rs.MovePróximo
Wend
Rs.Fechar
Definir Rs = Nada
Conexão Fechar
SetConn=Nada
Para i = 1 Para Ubound(Application("PageId"))
Response.Write("<a href='Test1.asp?Page="&i&"'>"&i&"</a> ")
Próximo
Tempo2 = Temporizador()
Response.Write("<br>"&(Time2-Time1)*1000)
'Application.Contents.Remove("PageId")
%>
O código de paginação tradicional é o seguinte: (doravante denominado programa antigo)
<%
Tempo1 = Temporizador()
Dim Conexão
Definir Conexão = Server.CreateObject("Adodb.Connection")
Conn.open "Driver={MicroSoft Access Driver (*.mdb)};Dbq="&Server.MapPath("db.mdb")
Dim Page, PageCounts, PageList
Dim Rs,Sql
Lista de páginas = 20
Página = Request.QueryString("Página")
Definir Rs = Server.CreateObject("Adodb.Recordset")
Sql = "Selecione * na ordem de teste por id desc"
Rs.Open Sql,Conn,1,1
Se Página = "" Então Página = 1
Se não (Rs.eof ou Rs.Bof), então
Rs.PageSize = ListadePáginas
Contagens de páginas = Rs.Contagem de páginas
Rs.AbsolutePage = Página
Terminar se
Para i = 1 para PageList
Se Rs.eof, então saia para
Response.Write(Rs(0)&"-----"&Rs(1)&"<br>")
Rs.MovePróximo
próximo
Para i = 1 para contagens de páginas
Response.Write("<a href='Test.asp?Page="&i&"'>"&i&"</a> ")
Próximo
Tempo2 = Temporizador()
Response.Write("<br>"&(Time2-Time1)*1000)
%>
Na verdade, a idéia geral é criar uma matriz global de Application("PageId"), e cada elemento salva o intervalo de ID do registro na página. Por exemplo, Application("PageId")(0) salva o ID de. o primeiro elemento. Então Application("PageId")(1) salva o primeiro ID da próxima página... e assim por diante. Quando você precisar acessar a i-ésima página, basta procurar o ID diretamente em [Application(. "PageId")(i- 1), Application("i") ) Dessa forma, você só precisa pesquisar o número necessário de registros de cada vez, em vez de pesquisar todos os registros todas as vezes. o primeiro acesso Quando o array Application("PageId") precisa ser criado, ele fica um pouco mais lento. Quando acessado pela enésima vez (N>1), a velocidade é quase 10 vezes mais rápida. Usei os dois programas acima. teste:
1. Existem 32.000 registros no banco de dados. O programa antigo leva cerca de 500 milissegundos para acessar uma página. O novo programa só atinge esse tempo durante o primeiro acesso e leva apenas cerca de 55 milissegundos de cada vez.
2. Aumente os dados para 64.000 registros. O programa antigo leva cerca de 1.000 milissegundos para acessar uma página. O novo programa também atinge esse nível quando o acessa pela primeira vez.
3. Aumente os dados para 128.000 registros. O programa antigo leva cerca de 1.900 milissegundos para acessar uma página, o novo programa leva cerca de 2.300 milissegundos para acessar uma página pela primeira vez e, então, cada acesso leva apenas cerca de 70 milissegundos.
O que precisa ser observado aqui é que toda vez que o banco de dados é modificado, Application("PageId") precisa ser reatribuído.
Experiência de pesquisa: (Em primeiro lugar, obrigado Ye Zi (DVBBS) pela sua experiência) Tente não usar o programa de paginação integrado, Rs.RecordCount consome muitos recursos. Por sua vez, estima-se que Rs.PageCount... também consome recursos, e o efeito do uso de Rs.GetRows() também é significativamente melhorado.
Após comparação, a velocidade e a eficiência do algoritmo folha são relativamente altas quando os registros são relativamente altos. Mas não é muito estável, às vezes (raramente) salta de cerca de 30ms para 1-200ms. Depois disso, a eficiência cai significativamente para 50-80 milissegundos e, quanto mais tarde, a eficiência diminui. A eficiência do novo algoritmo é relativamente baixa pela primeira vez, cerca de 500 milissegundos, mas é relativamente estável mais tarde, geralmente é de cerca de 50 milissegundos, e conforme o número de registros na biblioteca muda, essa velocidade permanece a mesma. Nada vai mudar. Da próxima vez tentarei combinar Ye Ye com meu algoritmo, mas o algoritmo de Ye Ye é realmente muito bom e versátil. Só posso usá-lo para conversar.