Foxty [งานต้นฉบับ]
เพิ่งศึกษาวิธีการเขียนอัลกอริธึมการเพจที่มีขนาดเล็กมาก ฉันได้แยกแยะออกแล้วและมีแนวคิดดังนี้:
ขั้นแรก จำเป็นต้องมีฟิลด์การกำหนดหมายเลขอัตโนมัติ (ID) ในฐานข้อมูล จากนั้นในการเข้าชมครั้งแรก ให้นำบันทึกทั้งหมดออกมา ปรับแต่งจำนวนบันทึกในแต่ละหน้า PageSize คำนวณจำนวนหน้า จากนั้นสร้างอาร์เรย์ PageId หนึ่งมิติ (PageCount) ตามจำนวนหน้า PageId (0 ) บันทึกเงื่อนไขการทดสอบเริ่มต้นของบันทึก จากนั้นสอดคล้องกับแต่ละองค์ประกอบ บันทึกรหัสขอบเขต ID ที่สอดคล้องกับแต่ละหน้า (
1. รหัสขอบเขต ID: หากลำดับการบันทึกฐานข้อมูล ID เป็นดังนี้: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
สมมติว่าคุณต้องเรียงลำดับตาม ID, PageSize = 5, Pagecount = 4, PageId(4)
ค่าของอาร์เรย์ PageId คือ PageId(0) = 1, PageId(1) = 5, PageId(2) = 10, PageId(3) = 15, PageId(4) = 16
เมื่อเข้าถึงเพจ i-th ให้ค้นหาเรคคอร์ดระหว่าง [PageId(i-1), PageId(i) โดยตรง เพื่อให้แน่ใจว่าจะดึงเฉพาะเรคคอร์ด PageSize เท่านั้นในแต่ละครั้ง
สมมติว่าคุณต้องเรียงลำดับตาม ID ในลำดับย้อนกลับ
ค่าของอาร์เรย์ PageId คือ PageId(0) = 16, PageId(1) = 12, PageId(2) = 7, PageId(3) = 2, PageId(4) = 1 เมื่อเข้าถึง i-th หน้า ค้นหา ID ที่เป็นของ [ PageId(i-1) , PageId(i) )
)
โดยตรง
บันทึกอาร์เรย์ PageId() ใน Application() เพื่อให้เข้าถึงได้ง่าย เพื่อให้ Application() ได้รับการเตรียมใช้งานในครั้งแรกที่มีการเข้าถึงเพจเจอร์เท่านั้น ส่วนของโค้ดมีดังนี้ (ต่อไปนี้จะเรียกว่าโปรแกรมใหม่)
<%
Time1 = ตัวจับเวลา ()
ดิม คอนน์
ตั้งค่า Conn = Server.CreateObject("Adodb.Connection")
Conn.open "Driver={ไดรเวอร์การเข้าถึง MicroSoft (*.mdb)};Dbq="&Server.MapPath("db.mdb")
'www.downcodes.com'
Dim Page, PageCounts, PageId, PageList
หรี่ Rs, SQL
ดิมอิสอินิท, ไอ
IsInit = False 'แฟล็กนี้ใช้เพื่อกำหนดว่า Application ("PageId") ได้รับการเตรียมใช้งานหรือไม่
PageList = 20 'ตั้งค่าข้อมูล 20 ชิ้นที่จะแสดงในแต่ละหน้า
ตั้งค่า Rs = Server.CreateObject("Adodb.Recordset")
Page = Request.QueryString("Page") 'โปรดทราบว่าจำเป็นต้องตรวจสอบหมายเลขหน้าสำหรับประเภท
หาก IsEmpty(Application("PageId")) ดังนั้น 'หาก Application("PageId") ยังไม่ได้เริ่มต้น ให้เริ่มต้นก่อน
Response.Write("เริ่มต้นแอป!<br>")
Sql = "Select * From test Order By Id Desc" 'สมมติว่าสิ่งนี้เรียงลำดับกลับกันตาม ID
Rs.open Sql,Conn,1,1 'รับวัตถุชุดระเบียน
ถ้าไม่ (Rs.Eof หรือ Rs.Bof) แล้ว
Rs.PageSize = PageList 'กำหนดจำนวนบันทึกต่อหน้า
PageCounts = Rs.PageCount
ReDim PageId(PageCounts) 'กำหนดอาร์เรย์ PageId ใหม่
สำหรับ i = 0 ถึง PageCounts 'เริ่มกำหนดค่าให้กับอาร์เรย์ PageId()
ถ้า Rs.eof ให้ออกเพื่อ
รหัสหน้า(i) = ฿("ID")
฿ ย้าย(PageList)
ต่อไป
฿MoveLast
PageId(PageCounts) = Rs("ID")
แอพลิเคชันล็อค()
แอปพลิเคชัน ("PageId") = PageId
แอปพลิเคชันปลดล็อค()
สิ้นสุดถ้า
฿ปิด
สิ้นสุดถ้า
IdStart = Clng(Application("PageId")(หน้า-1))
IdEnd = Clng(Application("PageId")(หน้า))
Sql = "เลือก * จากการทดสอบโดยที่ id<="&IdStart&" และ id>"&IdEnd&" "
Rs.open Sql,Conn,1,1
ในขณะที่ไม่ใช่ Rs.eof
Response.Write(rs(0)&"--"&rs(1))
฿MoveNext
เวนด์
฿ปิด
ตั้งค่า Rs = ไม่มีเลย
คอน.ปิด
SetConn=ไม่มีอะไร
สำหรับ i = 1 ถึง Ubound(Application("PageId"))
Response.Write("<a href='Test1.asp?Page="&i&"'>"&i&"</a> ")
ต่อไป
Time2 = ตัวจับเวลา ()
Response.Write("<br>"&(Time2-Time1)*1000)
'Application.Contents.Remove("PageId")
%>
รหัสเพจแบบดั้งเดิมมีดังนี้: (ต่อไปนี้จะเรียกว่าโปรแกรมเก่า)
-
Time1 = ตัวจับเวลา ()
ดิม คอนน์
ตั้งค่า Conn = Server.CreateObject("Adodb.Connection")
Conn.open "Driver={ไดรเวอร์การเข้าถึง MicroSoft (*.mdb)};Dbq="&Server.MapPath("db.mdb")
Dim Page, PageCounts, PageList
หรี่ Rs, SQL
รายการเพจ = 20
หน้า = Request.QueryString( "หน้า" )
ตั้งค่า Rs = Server.CreateObject("Adodb.Recordset")
Sql = "เลือก * จากลำดับการทดสอบด้วยรหัสรายละเอียด"
Rs.Open Sql,Conn,1,1
ถ้า Page = "" ดังนั้น Page = 1
ถ้าไม่ใช่ ( Rs.eof หรือ Rs.Bof ) จากนั้น
Rs.PageSize = รายการเพจ
PageCounts = Rs.PageCount
Rs.AbsolutePage = เพจ
สิ้นสุดถ้า
สำหรับ i = 1 ถึง PageList
ถ้า Rs.eof ให้ออกเพื่อ
Response.Write(Rs(0)&"-----"&Rs(1)&"<br>")
฿MoveNext
ต่อไป
สำหรับ i = 1 ถึง PageCounts
Response.Write("<a href='Test.asp?Page="&i&"'>"&i&"</a> ")
ต่อไป
Time2 = ตัวจับเวลา ()
Response.Write("<br>"&(Time2-Time1)*1000)
-
ที่จริงแล้ว แนวคิดโดยรวมคือการสร้างอาร์เรย์ส่วนกลางของ Application("PageId") และแต่ละองค์ประกอบจะบันทึกช่วง ID ของเรกคอร์ดในเพจ ตัวอย่างเช่น Application("PageId")(0) จะบันทึก ID ของ องค์ประกอบแรก จากนั้น Application("PageId")(1) จะบันทึก ID แรกของหน้าถัดไป...และอื่นๆ เมื่อคุณต้องการเข้าถึงหน้าที่ i-th เพียงค้นหา ID โดยตรงใน [Application( "PageId")(i- 1) , Application("i") ) ด้วยวิธีนี้ คุณจะต้องค้นหาเพียงจำนวนเรคคอร์ดที่ต้องการในแต่ละครั้ง แทนที่จะค้นหาเรคคอร์ดทั้งหมดทุกครั้ง อย่างไรก็ตาม วิธีการนี้ถูกนำมาใช้ การเข้าถึงครั้งแรก เมื่อจำเป็นต้องสร้าง array Application("PageId") จะช้ากว่าเล็กน้อย เมื่อเข้าถึงครั้งที่ N (N>1) ความเร็วจะเร็วขึ้นเกือบ 10 เท่า ทดสอบ:
1. มีบันทึก 32,000 รายการในฐานข้อมูล โปรแกรมเก่าใช้เวลาประมาณ 500 มิลลิวินาทีในการเข้าถึงหนึ่งเพจ
2. เพิ่มข้อมูลเป็น 64,000 รายการ โปรแกรมเก่าใช้เวลาประมาณ 1,000 มิลลิวินาทีในการเข้าถึงหนึ่งเพจ
3. เพิ่มข้อมูลเป็น 128,000 บันทึก โปรแกรมเก่าใช้เวลาประมาณ 1900 มิลลิวินาทีในการเข้าถึงหนึ่งหน้า โปรแกรมใหม่ใช้เวลาประมาณ 2300 มิลลิวินาทีในการเข้าถึงหนึ่งหน้าเป็นครั้งแรก จากนั้นการเข้าถึงแต่ละครั้งจะใช้เวลาประมาณ 70 มิลลิวินาทีเท่านั้น
สิ่งที่ต้องสังเกตที่นี่คือทุกครั้งที่มีการแก้ไขฐานข้อมูล Application("PageId") จะต้องได้รับการกำหนดใหม่!
ประสบการณ์การวิจัย: (ก่อนอื่น ขอขอบคุณ Ye Zi (DVBBS) สำหรับประสบการณ์ของคุณ) พยายามอย่าใช้ โปรแกรมเพจจิ้งในตัว Rs.RecordCount สิ้นเปลืองทรัพยากรมาก ในทางกลับกัน มีการประมาณว่า Rs.PageCount... ยังใช้ทรัพยากร และผลของการใช้ Rs.GetRows() ก็ได้รับการปรับปรุงอย่างมีนัยสำคัญเช่นกัน
หลังจากการเปรียบเทียบ ความเร็วและประสิทธิภาพของอัลกอริธึมลีฟจะค่อนข้างสูงเมื่อบันทึกค่อนข้างสูง แต่มันไม่เสถียรนัก บางครั้ง (ไม่บ่อยนัก) กระโดดจากประมาณ 30 มิลลิวินาทีเป็น 1-200 มิลลิวินาที หลังจากนั้น ประสิทธิภาพจะลดลงอย่างมากเหลือ 50-80 มิลลิวินาที และประสิทธิภาพจะลดลงในเวลาต่อมา ประสิทธิภาพของอัลกอริทึมใหม่ค่อนข้างต่ำในครั้งแรกประมาณ 500 มิลลิวินาที แต่ค่อนข้างเสถียร หลังจากนั้นโดยทั่วไปจะอยู่ที่ประมาณ 50 มิลลิวินาที และเมื่อจำนวนบันทึกในไลบรารีเปลี่ยนแปลง ความเร็วนี้จะยังคงเท่าเดิม จะไม่มีอะไรเปลี่ยนแปลง คราวหน้าฉันจะลองรวมเย่เย่เข้ากับอัลกอริทึมของฉัน แต่อัลกอริทึมของเย่เย่นั้นดีและหลากหลายมากจริงๆ ฉันสามารถใช้มันเพื่อแชทเท่านั้น