M$$QL กับการ ดึงข้อมูล แบบ limit

คือว่าผมเคยแต่ใช้ MySQL เวลาดึงข้อมูลตามจำนวนข้อมูลที่กำหนดไว้ก็ดึง limit x,y
แต่มาใน M$$QL มีคนนะนำให้ใช้ select top(y)(กรณีนี้จะได้จำนวนรายการตั้งแต่ 1... y) แต่ ผมจะดึงข้อมูลอย่างไรดีครับ ให้มันจำกัดจำนวน เช่น 10000 ต่อ 1 ครั้ง (มีข้อมูลเป็นหลักล้านนะครับ) แล้วข้อมูลก็เรียงต่อกันไม่แสดงขึ้นมาซ้ำนะครับ

sugree's picture

ใช้ limit เหมือนปกติไม่ได้เหรอครับ

ตัวอย่างในการใช้ Limit แบบ ของ MSSOL (เฉพาะ MSSQL 2005)

WITH Salesman as(
SELECT c.FirstName, c.LastName, ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS 'Row Number', s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson s JOIN Person.Contact c on s.SalesPersonID = c.ContactID
JOIN Person.Address a ON a.AddressID = c.ContactID)
SELECT FirstName, LastName SalesYID, PostalCode
FROM Salesman
WHERE [Row Number] Between 1 and 10000 ---- Limit x, y

สงสัยครับว่า อย่างงี้มันโหลดมาทั้งหมดรอบนึงก่อน แล้วใส่ tmp table Salesman หรือป่าวครับ
จากนั้นก็มา SELECT จาก Salesman อีกรอบ ผมไม่แม่น MSSQL เท่าไร
แต่ถ้ามองจาก SQL แล้ว รอบแรกที่ Query ใส่ Salesman
มันน่าจะอ่านทั้ง table Sales.SalesPerson
แล้วทำการ scan แบบ equal reference กับ table Person.Contact และ Person.Address
แล้วค่อยมา Scan ทั้ง Salesman เพื่อเทียบ tmp column [Row Number] อีกทีหรือป่าวครับ
ถ้าเป็นแบบนี้ database น่าจะทำงานเยอะมากเลยนะครับ

ถ้าใช้คำสั่ง Top ตั้งแต่ตอนดึงข้อมูลจาก Sales.SalesPerson น่าจะเร็วกว่านะครับ
แล้วทำการ scan แบบ equal reference ก็ได้ข้อมูลแล้ว

ทำแบบนี้ database น่าจะทำงานน้อยกว่า

แล้วตอน fetch ก็ fetch แบบไม่ต้องอ่านข้อมูล แค่ให้วิ่งข้าม row นั้นไป
แต่ตรงนี้ต้องหา library ที่ support แต่ถ้าไม่ support ก็ข้อมูลที่จะส่งก็จะมากกว่า -_-!

คำสั่ง with ใช้เพื่อกำหนดขอบเขตของข้อมูลที่เราสนใจหรือต้องการนำไปประมวลผลต่อ(Query-Scoped) ไม่ได้เก็บเป็น TEMP Table อย่าที่เข้าใจครับ เพราะถ้าหากลอง รันเฉพาะ with saleman as (...) โดยไม่ตามด้วย Manipulation Statements จะเกิด Error หาำกเป็น TEMP Table ต้องมีการบันทึก Database tempdb ของ System Database
ในกรณีที่ใช้ Top เร็วกว่าจริงครับ หากเทียบกับการใช้ limit x เพียงอย่างเดียว แต่หากเป็นช่วงที่ถัดจาก record แรกไปนั้น จะไม่เป็นเช่นนั้นครับ เพราะต้องอาศัย subquery ในการแบ่งช่วงข้อมูล
Exp.
SELECT TOP 10 a.* FROM SAMPLE a
WHERE a.PK NOT IN (SELECT TOP 10 b.PK FROM SAMPLE b)
ORDER BY a.PK ---- ข้อมูล ช่วง 11 - 20

ตามตัวอย่างตรวจสอบ ด้วย Execution Plan จะกิน Performance มากกว่าครับ

khao_lek's picture

ขอบคุณครับ

khao_lek's picture

http://www.select-sql.com/mssql/how-to-make-limit-from-to-in-mssql-2005.html

ย้าย Codenone

ประกาศย้าย Codenone ไปใช้ Forum ของ Blognone แทนครับ ตามไปตั้งกระทู้ต่อได้ที่ Codenone Forum (รายละเอียดอ่านจากกระทู้ ย้าย Codenone ไปรวมกับ Blognone)

กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น