Mar
09
2009
เรื่องเล็กๆที่ไม่เล็กกับ Context Switch
Written by Administrator   

    เทคนิคในการ Tuning เพื่อให้ SQL ที่เขียนนั้นมีประสิทธิภาพสูงสุดนั้น มีหลากหลาย  ซึ่งขึ้นอยู่กับความถนัดและสถานการณ์นั้น  หนึ่งในสิ่งที่ผมต้องคำึนึงเสมอก็คือ Context Switch

    อย่างที่เราทราบกันดีกว่า ใน Oracle มี Engineที่ใช้ในการ Process PL/SQL Statement มี 2 Engine คือ PL/SQL Engine และ SQL Engine เมื่อเราเขียน คำสั่ง PL/SQL  เช่น สร้าง Cursor  ซึ่งเป็นวิธีที่ Programmer มื่อใหม่ (รวมถึงผมเองด้วย Laughing ) ชอบใช้เขียนเพื่อดึงข้อมูลเยอะๆมาแสดงผลหรือ Process ต่อไป โดยทีไม่รู้  หรือไม่ได้ระวังถึงผลที่กระทบกับเรื่อง Performance (ก็ตอน Develop ข้อมูลมันหลัก 10 หรือ100  records  แต่งานจริง อย่างน้อยก็หลัก หมื่นหรือหลักแสน records )   


     sql > create table t as select * from all_objects where 0 =1  ;

     sql>  set timing on  

    ต.ย. การสร้าง Cursor

BEGIN
    FOR x IN (SELECT * FROM all_objects)
    LOOP
        INSERT INTO t
        (owner, object_name, subobject_name, object_id,
        data_object_id, object_type, created, last_ddl_time,
        timestamp, status, temporary, generated, secondary,namespace,edition_name)
        VALUES
        (x.owner, x.object_name, x.subobject_name, x.object_id,
        x.data_object_id, x.object_type, x.created,
        x.last_ddl_time, x.timestamp, x.status, x.temporary,
        x.generated, x.secondary,x.namespace , x.edition_name);
    END LOOP;
COMMIT;
END;

 เวลาที่ใช้ คือ 17.56 วินาที  ได้ข้อมูล   68,440 records

   การทำงานของ Cursor คือ  fetch c_data ทีละ record  จนจบ  และในขณะที่ Cursor fetch ข้อมูลนั้นเอง ทำให้เกิด Context Switch ขึ้น  และปกติแล้ว Context Switch เกิดขึ้นอย่างรวดเร็วมาก(ประมาณ 1/1000 วินาที) แต่ปัญหาคือ เกิดขึ้นเยอะมาก เช่น Cursor ที่มีข้อมูล  100,000 record เิิกิด Context Switch 100,000 ครั้ง  และนี่ก็คือ เวลาที่เสียไปโดยเปล่าประโยชน์จริงๆ  

   Context Switch จึงเป็นปัญหาสำคัญของ Performance  ถ้าลองคิดดูว่า ข้อมูลที่เพิ่มขึ้นทุกๆวัน หลังจากถูกใช้งาน  ถ้ามีการเขียน Code โดยไม่คำนึงถึงปัญหาเหล่านี้  เราจึงพบปัญหาว่า หลังจากใช้งานจริง  ระบบทำงานช้าลง  สุดท้ายก็ต้องให้ DBA มา Tune Database ให้  แต่จริงๆ แล้ว สา่เหตุที่เกิดจากการ Code ที่เขียนโดยรู้เท่าไม่ถึงการณ์

   ดังนั้น ทางออกของปัญหานี้ ก็คือ  การลดจำนวน Context Switch หลักการง่ายๆ ก็คือ กรณีที่ต้อง Preocess กับ ข้อมูลเยอะๆ ให้ใช้คำสั่งที่ทำกับข้อมูลที่ละ หลายๆ  record ได้ เช่น Forall , bulk collect   

 ต.ย. bulk collect  ทำทีละ 10,000 records

sql > create table t2 as select * from all_objects where 0 =1  ;

sql >DECLARE

  TYPE ARRAY IS TABLE OF all_objects%ROWTYPE;
  all_data ARRAY;
CURSOR c_all IS  SELECT *  FROM all_objects;
BEGIN
    OPEN c_all;
    LOOP
    FETCH c_all  BULK COLLECT INTO all_data LIMIT 10000;
    FORALL i IN 1..all_data.COUNT
    INSERT INTO t2 VALUES all_data(i);
    EXIT WHEN c_all%NOTFOUND;
    END LOOP;
    CLOSE c_all;
END ;

เวลาที่ใช้คือ  11.68 วินาที   ได้ข้อมูล   68,440 records

   จาก 2 ตัวอย่่างจะเห็นได้ว่า เวลาต่างกันพอสมควร  เมื่อเทียบเป็นเปอร์เซ็นต์ ผลต่างของ Context Switch ยิ่งเห็นได้ชัดขึ้นเมื่อข้อมูลเยอะขึ้น เป็นหลักล้าน ซึ่งเป็นไปได้เมื่อมีการ Join  เช่้น  table 3 table join กัน โดยมี data 10,000 x  1,000  x 10 = 10,000,000  = 10 ล้าน ลักษณะนี้มีโอกาสเป็นไปได้มากทีเดียว 

  เล็กๆ น้อยๆ กับเวลาที่เสียไป  แต่เมื่อทำบ่อยๆ  เวลาที่เสียไปอาจจะมากจนคิดไม่ถึงทีเดียว   เหมือนกับ เรื่องของการดูแลสิ่งแวดล้อม  ลดขยะ ลดพลาสติก  ใช้ไฟให้น้อยลงคนละ 1 ดวง เพียงแค่นี้ก็เป็นการเริ่มต้นช่วยสิ่งแวดล้อมโลกได้มากทีเดียวครับ 

 

 

Comments
Add New Search
Wyatt Plautz  - à¹€à¸£à¸·à¹ˆà¸­à¸‡à¹€à¸¥à¹‡à¸à¹†à¸—ี่ไม๠    |223.205.130.xxx |2017-11-15 05:21:44
The best blog for home improvement http://interiordesignideas2017.weebly.com/
Write comment
Name:
Email:
 
Website:
Title:
UBBCode:
[b] [i] [u] [url] [quote] [code] [img] 
 
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Please input the anti-spam code that you can read in the image.

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."