วันพฤหัสบดีที่ 15 กุมภาพันธ์ พ.ศ. 2561

DB2/400 Advance

DB2/400 Advance

ทุก DB การจัดการจะ "เหมือนกัน" - มีแตกต่างกันใน รายละเอียด
หัวข้อนี้ จะพูดพยายาม อธิบายทางเทคนิค DB2/400 ในมุมมองทั่วไป น๊ะครับ

มาดูกันว่า  DB Engine คืออะไร ? ทำงานอย่างไร ?
งานพื้นฐาน
- DB ถ้าแค่มีหน้าที่  "จัดเก็บ"  เท่านั้น 
- เขียน SQL แค่นี้   Select *  from  lib.File   (ไม่มีอะไรต่อท้าย)
DB จะทำงานไม่ต่างจาก Text File  (ไม่ต้องซื้อ DB มาใช้)

DB Engine

ในการใช้งานจริง  เราทำมากกว่านั้น  และ  ต้องการ "ความรวดเร็ว"
DB Engine จึงถูกนำมาช่วยทำงาน

DB Engine คือ ชุดโปรแกรมที่ทำงานเบื้องหลัง "ตลอดเวลา"
สำคัญหรือไม่ ?   คงได้ยินว่าเราต้องซื้อ Server เฉพาะสำหรับ DB เลย
แสดงว่า  มันทำงานหนักมาก  ใช้ทั้ง CPU,RAM


ภาพแสดง  จัดการ DB Engine ที่แยก กลุ่ม RAM (Pool)  
ทำงานหนัก หรือ เบา  ดูจาก (Page ถูกเรียกใช้บ่อยแค่ไหน) 


งาน-1 : เมื่อบันทึก ข้อมูล  ลง File,Table 
- มันจะวิ่งไปหา   พื้นที่ว่าง (Disk) และ  สร้างตัวเชื่อมต่อกับ  ข้อมูล row สุดท้าย (link)
  (ไม่ขออธิบาย ระดับลึกกว่านี้น๊ะครับ  มันเยอะไป)
- มันจะสร้าง Run No ให้ประจำ Row  เรียก RRN หรือ  Relative Record Number
  Tip ใน SQL บางครั้ง  ใช้ เพื่อดูว่า  Row ไหน เกิดขึ้น ก่อน/หลัง

เพิ่มสักนิด  ข้อมูล 50,000 rows   การ "ค้นหา" ไปที่ rows สุดท้าย - ค้นหา 50,000 ครั้ง ?
      เพื่อความรวดเร็ว   ข้อมูลจะถูกจัดเป็นกลุ่ม เรียกว่า "Page" (เช่น 1 Page เก็บข้อมูลได้ 4K เป็นต้น) 
      ถ้า 1 row มีขนาด 4 byte  (คิดง่ายๆ) 1 Page จะเก็บข้อมูลได้  1,000 Rows  = จะเกิด 50 Page
      การ "ค้นหา" ข้างต้นจะทำแค่ 50 ครั้ง (ตามจำนวน Page) เท่านั้น  = "เร็วขึ้นมาก" (ว๊าว คิดได้ไงเนี่ยะ)

      แต่ ... ต้องแลกมาด้วย   ทำงานเพิ่มเล็กน้อย
       - จัดการ Page ตรวจถ้า Page  เต็มต้อง  "สร้าง Page ใหม่" ตัวชี้

      เมื่อมีอะไร  "ดี"  ย่อมมีอะไร  "ยุ่ง"  ตามมา  ต้องจัดการ
       - เมื่อลบข้อมูล 1 row  Page ก็จะเกิด "ที่ว่าง"
             ถ้าแต่ละ Page มี "ที่ว่าง" มากไป  จะเสียพื้นที่มาก
             ถ้าให้มัน  "ค้นหา" ในทุก Page ก็ "ช้า"
             >> ถ้าต้องการให้ มันจัดการพื้นที่  ก็ต้องสั่ง "ลดขนาด"   RgzPFM, Shrink, Compact ,...
             คุ้นๆมั๊ยครับ Admin ขอหยุดการใช้งาน 8 ชม. เพื่อ "ลดขนาด" 
             (ธนาคาร หยุดให้ใช้ internet Backing แค่ 8 ชม. ปีละ 3 ครั้งเท่านั้น - ลูกค้า  รับได้มั๊ย ?)

       - File ประเภท DataWareHouse (จำนวน row มหาศาล, ไม่มีค่อย  มีการลบข้อมูล)
         น่าจะปรับ ขนาด Page ให้  "ใหญ่"   (Admin อาจจะมองจัดการอีกระดับ เรียก ทำ Partition)

งาน-2 : เรียงข้อมูล ,"ค้นหาได้เร็ว"

- เขียน SQL ที่มี  Keyword = Order By 
        Select *  from  lib.File  Order By ...

  ทั่วไป  (ไม่จัดการอะไร)   การเรียงลำดับ จะเกิดขึ้นใน  Memory
        ข้อมูล 50,000 rows  เรียก SQL หลายเครื่องพร้อมกัน  Memory  ที่มี ทำงานได้เร็วพอมั๊ย ? 
        >>  ช้าก็  ซื้อ RAM เพิ่มซะ ... (แพง + ใส่จนเต็มแล้ว)
        >>  จัดการ ที่ DB Admin 
               เช่น ให้สิทธ์/แบ่งเวลากันใช้, ข้อมูลใช้บ่อย ให้มันจำไว้ และ เรียกใช้ซ้ำผ่าน Cache

  จัดการ ด้วยการสร้าง "Index"  (โดย DB Admin)
       DB Engine จะสร้าง Table ใหม่  "ที่เรียงข้อมูล"  ตามที่กำหนดไว้  (เช่น เรียงตาม InvoiceNo,Seq)
       เมื่อข้อมูลถูกบันทึก/แก้ไข  ก็ต้องมาทำกับ Table ใหม่นี้ด้วย

  ตย.  ระบบงาน  มีเรียกใช้   SQL   Lib.FileP  Order by Invoice,Seq  บ่อยๆ
  ให้สร้าง   Index  Lib.FileL1  ที่เรียงตาม   Invoice,Seq 
      (หลักการ Index จะเก็บแค่ RRN จาก P-File เท่านั้น)
  ทุกครั้งที่  บันทึก/แก้ไข  - DB Engine จะเพิ่มงาน  ไป "เรียงลำดับ"  ใน Index File ใหม่

   Q: ถ้าอย่างนั้น  ก็สร้างไว้ "เยอะๆ" ซิ  เรียกใช้เร็วดี
   A: ถ้าเข้าใจการทำงาน ด้วย -  Index  มีข้อเสีย  ชัดๆหลายเรื่อง (DB Admin จะเห็น)
        เช่น  มันทำงานหนักกว่า  ปรกติ    (5 P-File อาจจะสร้าง Indexไว้ 
                Dev จะมองว่าถ้า SQL Order By แล้วช้า  "ให้สร้าง Index ก็จะเร็ว"
                - Dev เขียน SQL ไว้  15 ตัว = ก็จะสร้าง Index ไว้ 15 ตัว
                DB Engine   ต้อง เพิ่ม(เสีย)เวลาทำงานกับ Index 15 ตัว 

Table ในระบบมี  500 File  อาจจะมี Index มากกว่า 5,000 File (ไม่ใช่ เรืองเล็กแล้ว)
ในขณะที่  "ความจริง"  Index ที่  "ต้องสร้าง"  อาจจะแค่  2-3 ตัวเท่านั้น
>> ถ้าระบบงานขนาดใหญ่  จึงต้องมี DB Admin  ตรวจ และ สร้าง Index
>> โดยใช้เครื่องมือ เช่น  Query Profile  บันทึกว่า  ช่วงเวลานี้   มีใครเรียกใช้ SQL อะไรบ้าง ?,เรียกถึ่แค่ไหน ?  ใช้เวลา "รอ" นานมากแค่ไหน  -> จำเป็นต้องสร้าง Index หรือไม่ ?
       
ภาพแสดง 1 Physical File มี Index (L-File) 9 ตัว
Index File บางตัว  ขนาดใหญ่  พอๆ กับ Physical File เลย

- ใช้ประโยชน์ จาก Index ต่อยอด  ใน   SQL ที่มี  Keyword = Where 
        Select *  from  lib.File  Where ...
  ถ้าพบว่า  Field ที่อยู่ใน  Where   มันเรียงลำดับ  เป็นส่วนหนึ่งใน  Index
  SQL นี้จะเรียกใช้  Index File

มาดูลึกๆ กันสักนิด

- การค้นหา  จะมีหลายเทคนิค  แต่ละ DB Engine ก็จะเลือก/พัฒนา  เพื่อให้ทำงานให้เร็วที่สุุด
  รายละเอียดลึกๆ มักเป็น "ความลับ" หรือ อ่านแล้วไม่รู้เรื่อง
- ที่เรียนมา คุ้นๆกัน  ได้แก่  Binary Tree - การค้นหา จะทำทีละครึ่ง (ด้านซ้าย หรือ ขวา) 
  เช่น จะค้นหา รหัสพนักงาน=450 จาก 1000 คน มันก็จะค้น ในกลุ่ม 1-500 เท่านั้น 
              ไม่เสียเวลาค้นในกลุ่ม 501-1000
         ใน 1-500 ยังแยกเป็น  1-250 กับ 251-500  มันจะค้นในกลุ่ม 251-500 เท่านั้น
         ...
         ดังนั้น  Page จะถูกจัดกลุ่ม ด้วยว่า  อยู่กลุ่ม 1-500 หรือ 501-1000  เป็นต้น

ลองอธิบาย  แบบชาวบ้าน  ให้  "เข้าใจและจัดการ" กันเองได้
  การ "ค้นหา" มี 2 แบบ คือ
  - ข้อมูล "น้อย"  ไม่ต้องสร้าง Index  ก็ทำงานเร็ว  (DB2/400 เรียก Table Scan)
            กลายเป็นว่า  ถ้าไปสร้าง Index  เครื่อง ก็จะทำงานหนักเกินไป
  - ข้อมูล "มาก"  ต้องสร้าง Index
            ถ้าไม่สร้าง Index  เครื่อง ก็จะทำงานหนักเกินไป

คนที่ต้อง "สร้าง Index"  ต้องคำนึงถึงรายละเอียดข้างต้น  ด้วย  (เริ่มเยอะ)

ภาพแสดง ตัววิเคราะห์การทำงานของ DB Engine

System i Navigator : Visual Explain






เป็นเครื่องมือ  ที่แสดงให้เห็น  DB Engine ทำงานอย่างไร  (เมื่อป้อน SQL)
ตย.ข้างบน 
- ภาพส่วนบน คือ  DB Engine  เรียกใช้  Index (มีกุญแจ) - Where ผมใส่ Field ที่ระบุใน Index File
- ภาพส่วนล่าง คือ  DB Engine  ไม่เรียกใช้ Index - Where ผมใส่ Field ที่ไม่ระบุใน Index File

การเขียน SQL ที่ดี คือ พยายามเขียนให้  "มันเรียกใช้ Index"
เขียน SQL เรื่องเดียวกัน  เขียนได้หลายแบบ  แบบไหน เร็วที่สุดล่ะ

ตย.  SQL 2 แบบนี้ ถ้าให้ผลลัพธ์เหมือนกัน   แบบไหน  "เหมาะที่สุด"
    Select  A.*  b    From  Lib.A  as A
    Left join  Lib.FileB on ...
กับ
    Select  A.*  ,(Select  b from Lib.FileB where ...)  From Lib.A

>> ความเร็ว ของการแสดง   จะดูจาก  "เวลารวมที่ใช้ไป"

ดูลำดับการทำงานของ DB Engine

a. File อะไร ?  กรอง Row หรือไม่   (ถ้ามี   Where เรียกใช้  index  จะเร็ว)
      >> จำนวน Row  หลัง  "กรอง"  ควรจะ "น้อย" 
              เช่น FileA  ได้  200 rows จาก 10,000 rows,  FileB  มีแค่ 50 rows
b. (ผลลัพธ์)  ไปทำอะไร ต่อ
    ทุกๆ FileA  1 rows ต้องไปหารายการที่ตรงกันใน FileB
     - ถ้าไม่มี Index ก็เท่ากับว่า  มันอาจจะ  "ทำงาน" มากสุด  200*50 = 10,000 ครั้ง
     - ถ้ามี Index   มันอาจจะ  "ทำงาน" มากสุด  200 + 200 (ค้นหา) = 400 ครั้ง
    เชื่อมต่อกับ FileA กับ FileB แบบ 1 ต่อ 1  จะได้ผล 200 rows
    เชื่อมต่อกับ FileA กับ FileB แบบ 1 : many  อาาจได้มากสุด=10,000 rows

c. (ผลลัพธ์)  ไปทำอะไร ต่อ
     Where กรองต่อ (ต้องอ่าน/ตรวจ เท่าจำนวน)
d. (ผลลัพธ์)  ไปทำอะไร ต่อ
     Order by (จุดนี้  จะเรียงใน Memory)

จากข้างต้น การลดจำนวน Row (ก่อน), การใช้ Where ที่อ้างอิง Index จะทำให้ "เร็ว"
บางกรณี ทดลองแล้วพบว่า  DB Engine มีสภาพดีมาก ไม่จำเป็น (เสียเวลา) ทำข้างต้น
ส่วนตัว  ทำ/คิด ตามลำดับ


ไม่มีความคิดเห็น:

แสดงความคิดเห็น