Import dữ liệu vào table Oracle bằng file data

Trong nhiều trường hợp ta cần đưa dữ liệu từ file vào DATABASE, cụ thể khi ta muốn import dữ liệu từ 1 file dữ liệu nào đó có trong DATABASE. Cách đơn giản nhất đó là viết câu lệnh Insert data vào bảng nhưng cách này rất mất thời gian và có thể làm treo hệ thống. Sau đây tôi sẽ hướng dẫn các bạn Import dữ liệu vào table Oracle bằng file chứa data như CSV, Excel, Txt…

Ta sử dụng phần mềm Oracle SQL Developer được cung cấp miễn phí bởi Oracle, có thể chạy ngay mà không cần cài đặt.

Ví dụ ta có file diemso.csv, cần đưa dữ liệu này vào bảng DIEMSO có các cột tương tự nhau.

Các bước chính để import dữ liệu vào Oracle

B1. Đầu tiên ta nháy đúp vào bảng nó, nó sẽ hiển thị sang màn hình làm việc chính các thông tin của bảng này. Ta có thể xem các thông tin của bảng như: thông tin các cột, thông tin data trong đó, các thông tin khác như index, contrain…

B2. Ta chọn sang tab data, nếu có dữ liệu thì nó sẽ show một phần dữ liệu ra cho ta có thể xem.

B3. Ta chọn Action… ở góc bên phải màn hình. Chọn Import data. Màn hình chọn file sẽ hiện ra để ta đi tìm file để import.

B4. Chọn đến file cần import, ở đây ta chọn đến file diemso.csv

B5. Từ đây ta chủ yếu chọn Next, mọi tham số ta để mặc định. Lưu ý đến màn hình số 4, phần map giữa cột của file csv với cột của TABLE trong DATABASE. Ta cần để ý chọn để map cho đúng cột, vì có thể thứ tự các cột trong csv có thể khác. Với cột có DATA là DATETIME ta cũng cần lưu ý định dạng để hệ thống có thể import vào đúng.
Ví dụ định dạng trong file csv là DD/MM/YYYY thì ta phải nhập định dạng này dưới phần MAP ID(phía bên phải).

B6. Sau đó Next đến bước cuối cùng, ta click verify. Tất cả SUCCESS là OK.

B7. Sau đó nhấn Finish. Chờ 1 lát thế là xong. Cách import này rất nhanh. Thay cho việc gen câu lệnh để insert hàng hoạt dữ liệu vào TABLE.

Trên đây là cách import dữ liệu vào table Oracle thông qua file CSV. Ta cũng có thể thao tác tương tự đối với file txt hoặc file excel… để đưa dữ liệu vào bảng thay vì phải dụng câu lệnh insert.

Có thể bạn quan tâm:

Quản trị Oracle trên Window: DATABASE, SCHEMA, TABLESPACE, TABLE

Hệ quản trị Oracle là hệ quản trị hàng đầu trên thế giới hiện nay, vượt lên trên cả SQL Server, MySQL… Hầu hết các hệ thống lớn và quan trọng đòi hỏi tính toàn vẹn dữ liệu cao, tốc độ xử lý nhanh… đều sử dụng Oracle. Ví dụ các hệ thống của ngân hàng, chứng khoán, các công ty lớn… Do vậy việc quản trị cơ sở dữ liệu Oracle luôn là một ngành hot do đó Oracle có cả một hệ thống tài liệu, đào tạo cho các chuyên gia về Oracle. Oracle có thể được cài đặt cả trên Window và Linux, sau đây mình xin hướng dẫn một số thao tác cơ bản về quản trị Oracle trên Window.

Trong khuôn khổ bài viết mang tính ghi chú lại để có thể sử dụng sau này và chia sẻ với những người mới. Nên mình chỉ hướng dẫn những việc liên quan đến 4 đối tượng chính sau: Database, Schema, Tablespace, Table.

Tạo mới một Database mới

Do server test đã có 1 database backup là APEX, để học mình sẽ tạo một database mới để không ảnh hưởng đến database backup APEX này.
Hiện server của hệ điều hành là Windown, phiên bản Oracle là 11g.
Ta chạy file dbca.bat nằm trong thư mục cài đặt Oracle ban đầu của ta:
C:\app\oracle\product\11.2.0\dbhome_1\BIN
Phần tạo này giao diện trực quan nên ta nhìn vào có thể tự chọn được. Ta chỉ cần lưu ý khi tại bước 7 cần tích chọn vào Enable Archiving để sau này có thể sử dụng RMAN để backup hoặc restore GAP file.

Tạo mới một schema để thao tác

Với ORACLE thì 1 DATABASE có thể tạo được nhiều SCHEMA, SCHEMA được quản lý bởi USER. Ta sẽ tạo một SCHEMA để thao tác trên đó. Một USER có thể quản lý nhiều SCHEMA.
Ta có thể dụng SQL Developer đăng nhập với quyền SYSDBA với user SYS hoặc SYSDBA để tạo mới một SCHEMA.
Create user TESTSQL01 identified by 123456;
Phân quyền lớn nhất cho SCHEMA này(test thì để thế này, thật thì tùy theo từng SCHEMA).
grant dba to TESTSQL01;

Tạo mới một TABLESPACE mới của SCHEMA

Như ta đã biết, một TABLE sẽ được lưu trong một TABLESPACE nhất định. Mỗi TABLESPACE có thể có một hoặc nhiều TABLESPACE.
Để kiểm tra dung lượng TABLESPACE và danh sách các TABLESPACE của SCHEMA ta dùng câu lệnh:
select b.tablespace_name,
b.MEGS,
(b.MEGS - a.MEGS_FREE) as ALLOCATED_MEGS,
round(((b.MEGS - a.MEGS_FREE) / b.MEGS) * 100) PCT_USED,
a.MEGS_FREE, EXTENSIBLE_MEGS
from (select tablespace_name, round(sum(bytes / 1024 / 1024)) MEGS_FREE
from dba_free_space
group by tablespace_name) a,
(select tablespace_name, round(sum((bytes / 1024 / 1024)),0) MEGS,
round(
sum(
case when autoextensible = 'YES' then (maxbytes - bytes)/1024/1024
else 0
end
),0) EXTENSIBLE_MEGS
from dba_data_files
group by tablespace_name
) b
where a.tablespace_name(+) = b.tablespace_name
order by 4 desc;
Ta sẽ tạo mới một TABLESPACE bằng câu lệnh:
create tablespace TESTTABLESPACE
logging datafile 'D:/app/oracle/oradata/PKTUY01/testtbsp01.dbf'
size 32m
autoextend on
next 32m maxsize 50m
extent management local;
Ta có thể sửa để nới thêm dung lượng cho TABLESPACE bằng câu lệnh:
ALTER DATABASE
DATAFILE 'D:/app/oracle/oradata/PKTUY01/testtbsp01.dbf'
RESIZE 60M;
Hoặc nếu ổ đĩa hết dung lượng ta có thể thêm datafile bằng câu lệnh:
ALTER TABLESPACE TESTTABLESPACE
ADD DATAFILE ‘E:/PKTUY01/testtbsp02.dbf’
SIZE 200M;

Tạo mới một TABLE trên TABLESPACE

CREATE TABLE GIAHAN(
SMC NVARCHAR2(100),
datcre DATE
)
TABLESPACE TESTTABLESPACE
STORAGE ( INITIAL 50K);
Ta cần có một chiến lược hợp lý để tiến hành lưu trữ TABLESPACE sao cho hợp lý. Làm sao dung lượng trống của ổ đĩa phù họp, các TABLESPACE không bị đầy tránh gây ảnh hưởng đến vận hành hệ thống.

Quản trị Oracle nói chung và quản trị Oracle trên Window nói riêng đòi hỏi một kiến thức nhất định về kiến trúc của Oracle cũng như về hệ điều hành. Nhìn chung việc cài đặt và quản trị Oracle trên Window khá đơn giản nhưng vì Window không ổn định Linux nên đối với các công ty lớn thường cài đặt Oracle trên Linux.

Để đảm bảo tính ổn định của hệ thống, bạn có thể quan tâm đến một số bài viết sau:

Oracle chuyển hàng thành cột dữ liệu

Trong việc làm báo cáo ta thường xuyên gặp các tình huống thống kê từ raw data phải chuyển dữ liệu từ hàng sang cột. Ta có thể sử dụng Excel để xử lý nhưng từ Oracle 10i thì có hỗ trợ câu lệnh PIVOT để xử lý.
Ta có thể test thử hàm này với giả dữ liệu như sau:

+ Chuẩn bị bảng và data:

—-create table

CREATE TABLE vn_temp_test_pivote (
C_MONTH VARCHAR2(15) NULL,
C_CORIG VARCHAR2(15) NULL,
C_VOLUME NUMBER(5) NULL);

—-test data

insert into vn_temp_test_pivote
values('201801','A',123);

insert into vn_temp_test_pivote
values('201801','B',121);

insert into vn_temp_test_pivote
values('201801','C',122);

insert into vn_temp_test_pivote
values('201802','A',1);

insert into vn_temp_test_pivote
values('201802','B',2);

insert into vn_temp_test_pivote
values('201802','C',3);

insert into vn_temp_test_pivote
values('201803','A',10);

insert into vn_temp_test_pivote
values('201803','B',20);

insert into vn_temp_test_pivote
values('201803','C',30);

Đây ví dụ ta có số lượng view(C_VOLUME) của từng C_CORIG trong từng tháng(C_MONTH).
Dữ liệu được trình bày:

C_MONTH C_CORIG C_VOLUME
201801 A 123
201801 B 121
201801 C 122
201802 A 1
201802 B 2
201802 C 3
201803 A 10
201803 B 20
201803 C 30

+ Ta cần nhìn xem số lượng view của các tháng theo từng loại C_CORIG, ta sử dụng hàm PIVOTE như sau:

SELECT *
FROM vn_temp_test_pivote PIVOT (SUM(C_volume)
FOR C_MONTH
IN ('201801' AS p_201801,
'201802' AS p_201802,
'201803' AS p_201803));

Kết quả:

C_CORIG p_201801 p_201802 p_201803
A 123 1 10
B 121 2 20
C 122 3 30

+ Như ta thấy ở ví dụ trên, nhược điểm của PIVOTE là ta phải liệt kê từng dữ liệu của cột cần chuyển sang hàng, nhưng ta có thể lấy tự động các tháng phát sinh không?
Oracle có hỗ trợ việc này nhưng PIVOTE chỉ có thể hiển thị data nằm trong XML:

SELECT *
FROM vn_temp_test_pivote PIVOT XML (SUM (C_VOLUME)
FOR C_MONTH
IN (SELECT DISTINCT C_MONTH FROM vn_temp_test_pivote));

Kết quả:

C_CORIG XML
A <XML>
B <XML>
C <XML>

Để lấy dữ liệu ra để trình bày ta phải đọc chuỗi XML theo khuôn dạng để trình bày ra.

SELECT C_CORIG,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[1]/column[2]') p1,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[2]/column[2]') p2,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[3]/column[2]') p3,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[4]/column[2]') p4,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[5]/column[2]') p5,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[6]/column[2]') p6,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[7]/column[2]') p7,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[8]/column[2]') p8,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[9]/column[2]') p9,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[10]/column[2]') p10,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[11]/column[2]') p11,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[12]/column[2]') p12,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[13]/column[2]') p13,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[14]/column[2]') p14,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[15]/column[2]') p15,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[16]/column[2]') p16,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[17]/column[2]') p17,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[18]/column[2]') p18,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[19]/column[2]') p19,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[20]/column[2]') p20,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[21]/column[2]') p21,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[22]/column[2]') p22,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[23]/column[2]') p23,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[24]/column[2]') p24,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[25]/column[2]') p25,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[26]/column[2]') p26,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[27]/column[2]') p27,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[28]/column[2]') p28,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[29]/column[2]') p29,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[30]/column[2]') p30
FROM (
SELECT *
FROM vn_temp_test_pivote PIVOT XML (SUM (C_VOLUME)
FOR C_MONTH
IN (SELECT DISTINCT C_MONTH FROM vn_temp_test_pivote))

) ;

Kết quả:

C_CORIG p1 p2 p3 p4 p5 p6...
A 123 1 10 null null
B 121 2 20 null null
C 122 3 30 null null

Phần này ta có thể liệt kê dài ra hoặc có thể check trước sau đó gen câu lệnh rồi ghép vào với nhau nếu muốn đẹp.
Được như thế này rồi nhưng ta vẫn chỉ là định nghĩa cột khi viết thôi, để map lại cột tự động(p1,p2…) với data(201801,201802…) ta sử dụng lấy dữ liệu ở cột 1 và chỉ lấy 1 dòng (vì tất cả các dòng là như nhau) sau đó UNION ALL lại là được:

SELECT '1_Code Origin' Code_Origin,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[1]/column[1]') A1,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[2]/column[1]') A2,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[3]/column[1]') A3,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[4]/column[1]') A4,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[5]/column[1]') A5,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[6]/column[1]') A6,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[7]/column[1]') A7,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[8]/column[1]') A8,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[9]/column[1]') A9,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[10]/column[1]') A10,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[11]/column[1]') A11,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[12]/column[1]') A12,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[13]/column[1]') A13,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[14]/column[1]') A14,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[15]/column[1]') A15,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[16]/column[1]') A16,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[17]/column[1]') A17,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[18]/column[1]') A18,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[19]/column[1]') A19,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[20]/column[1]') A20,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[21]/column[1]') A21,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[22]/column[1]') A22,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[23]/column[1]') A23,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[24]/column[1]') A24,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[25]/column[1]') A25,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[26]/column[1]') A26,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[27]/column[1]') A27,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[28]/column[1]') A28,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[29]/column[1]') A29,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[30]/column[1]') A30
FROM (
SELECT *
FROM vn_temp_test_pivote PIVOT XML (SUM (C_VOLUME)
FOR C_MONTH
IN (SELECT DISTINCT C_MONTH FROM vn_temp_test_pivote))

) where rownum=1
UNION
SELECT C_CORIG,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[1]/column[2]') p1,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[2]/column[2]') p2,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[3]/column[2]') p3,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[4]/column[2]') p4,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[5]/column[2]') p5,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[6]/column[2]') p6,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[7]/column[2]') p7,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[8]/column[2]') p8,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[9]/column[2]') p9,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[10]/column[2]') p10,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[11]/column[2]') p11,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[12]/column[2]') p12,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[13]/column[2]') p13,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[14]/column[2]') p14,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[15]/column[2]') p15,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[16]/column[2]') p16,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[17]/column[2]') p17,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[18]/column[2]') p18,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[19]/column[2]') p19,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[20]/column[2]') p20,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[21]/column[2]') p21,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[22]/column[2]') p22,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[23]/column[2]') p23,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[24]/column[2]') p24,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[25]/column[2]') p25,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[26]/column[2]') p26,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[27]/column[2]') p27,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[28]/column[2]') p28,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[29]/column[2]') p29,
EXTRACTVALUE (C_MONTH_XML, '/PivotSet/item[30]/column[2]') p30
FROM (
SELECT *
FROM vn_temp_test_pivote PIVOT XML (SUM (C_VOLUME)
FOR C_MONTH
IN (SELECT DISTINCT C_MONTH FROM vn_temp_test_pivote))

);

Kết quả:

C_CORIG p1 p2 p3 p4 p5 p6...
C_CORIG 201801 201802 201803...
A 123 1 10 null null
B 121 2 20 null null
C 122 3 30 null null

Oracle thông báo về trạng thái các TABLESPACE

Mình cũng chưa nắm được rõ về cấu trúc đặt dữ liệu của Oracle lắm, chỉ biết rằng data sẽ được đặt trong TABLESPACE. Trong 1 DATABASE có nhiều TABLESPACE, mỗi TABLESPACE có thể chứa 1 hoặc nhiều TABLE, nhưng 1 TABLE chỉ được nằm trong 1 TABLESPACE duy nhất.

TABLESPACE được khai báo khi tạo, có địa chỉ đặt ở ổ cứng xác định và được khai báo dung lượng trước. Nếu lượng data vượt quá dung lượng TABLESPACE thì hệ thống sẽ không ghi vào được nữa. Do vậy phải thường xuyên kiểm tra TABLESPACE xem có cái nào gần đầy thì phải nới ra, có thể nới rộng nhiều nhưng thường người ta nới dần dần, dùng đến đâu thì nới tới đó.

Trong thực tế triển khai, nhiều trường hợp không để ý đến TABLESPACE đầy hệ thống sẽ gặp lỗi không thể ghi dữ liệu nên việc DBA phải thường xuyên kiểm tra và nới TABLESPACE nếu cần.

Để kiểm tra thông tin về TABLESPACE ta có thể sử dụng câu lệnh SQL sau để lấy thông tin:

 

select b.tablespace_name,
b.MEGS,
(b.MEGS - a.MEGS_FREE) as ALLOCATED_MEGS,
round(((b.MEGS - a.MEGS_FREE) / b.MEGS) * 100) PCT_USED,
a.MEGS_FREE, EXTENSIBLE_MEGS
from (select tablespace_name, round(sum(bytes / 1024 / 1024)) MEGS_FREE
from dba_free_space
group by tablespace_name) a,
(select tablespace_name, round(sum((bytes / 1024 / 1024)),0) MEGS,
round(
sum(
case when autoextensible = 'YES' then (maxbytes - bytes)/1024/1024
else 0
end
),0) EXTENSIBLE_MEGS
from dba_data_files
group by tablespace_name
) b
where a.tablespace_name(+) = b.tablespace_name
order by 4 desc;

 

Với các thông tin này ta sẽ biết tình trạng của từng TABLESPACE và nới ra nếu cần.

Ta có thể tự động hóa hàng ngày thông báo qua email tình trạng của TABLESPACE bằng cách đặt crontab run câu lệnh này và gửi email.
Cao cấp hơn, ta cũng có thể làm cho hệ thống tự động kiểm tra TABLESPACE nào đầy thì tiến hành nới ra 1 khoảng. Ví dụ câu lệnh SQL trên ta check xem TABLESPACE nào có dung lượng còn dưới 10% thì tiến hành tự động nới TABLESPACE đó thêm 10% dung lượng hiện có và thông báo tới DBA.

Một bài viết chi tiết về TABLESPACE, rảnh đọc sau: http://www.oravn.com/viewtopic.php?t=48

Tối ưu (turning) câu lệnh PL/SQL: Việc JOIN và lấy dữ liệu trong câu lệnh SELECT

Trước đây ở công ty C mình cũng ít làm việc về Report nhưng các hàm query lấy dữ liệu thì cũng phải dùng thường xuyên. Các anh làm về Database cũng hay cảnh báo mọi người việc sử dụng câu lệnh SELECT ALL thì không được dùng. Việc SELECT ALL là câu lệnh SELECT *, cũng như việc SELECT những cái gì cần lấy chứ không nên lấy những cột mà không cần dùng.
Câu lệnh SELECT liên quan đến chỉ số I/O của hệ thống. SELECT càng nhiều thì càng làm tăng I/O và ảnh hưởng đến hiệu năng của hệ thống. Nôm na I/O là Input và Output giữa đĩa cứng để dữ liệu và RAM của server, dữ liệu sẽ đi qua cổng I/O này và nếu lớn nó sẽ làm ngẽn hệ thống.
Ví dụ điển hình là câu lệnh:
(1) SELECT COUNT(*) FROM TABLE_A WHERE A=B;
sẽ cho cùng kết quả với câu lệnh:
(2) SELECT COUNT(COLUMN_A1) FROM TABLE_A WHERE A=B;
và câu lệnh:
(3) SELECT COUNT(1) FROM TABLE_A WHERE A=B;

Với câu lệnh 1, hệ thống sẽ lấy toàn bộ các cột dữ liệu và tiến hành đếm các dòng ở các cột này. Việc này sẽ làm tăng I/O ảnh hưởng đến hệ thống và tất nhiên chạy chậm hơn.
Với câu lệnh 2, hệ thống sẽ lấy 1 cột COLUMN_A1 dữ liệu và tiến hành đếm các dòng ở các cột này. Câu lệnh này hệ thống cũng sẽ lấy dữ liệu ở cột COLUMN_A1 ra và đếm, I/O tốn ít hơn và câu lệnh sẽ nhanh hơn.
Với câu lệnh 3, hệ thống sẽ tự hiểu việc sẽ đếm toàn bộ các dòng trong bảng theo điều kiện gì đó. Hệ thống sẽ cần rất ít I/O nên câu lệnh sẽ nhanh hơn và đảm bảo được hiệu năng của hệ thống.

Từ lý thuyết về I/O và ví dụ trên, ta có thể tối ưu các câu lệnh JOIN và lấy dữ liệu sao cho hợp lý, tối ưu được hiệu năng hệ thống nhất là chỉ số I/O. Tránh việc gây nghẽn hệ thống, làm hệ thống giảm được tải, các câu lệnh chạy được nhanh hơn.

Ví dụ:
Câu lệnh chưa tối ưu: Lấy lương từng nhân sự phòng IT của tháng 12/2018

SELECT EP.ID,EP.NAME,SL.AMOUNT
FROM EMPLOYEE EP, SALARY SL
WHERE EP.ID=SL.ID
AND EP.IDDE='IT'
AND SL.MONTH='201812';

Ta có thể tối ưu lại để đỡ tốn I/O như sau:

SELECT EP.ID,EP.NAME,SL.AMOUNT
FROM (SELECT ID,NAME FROM EMPLOYEE WHERE IDDE='IT') EP, (SELECT EPID,AMOUNT FROM SALARY WHERE MONTH='201812') SL
WHERE EP.ID=SL.EPID;

Phần này ta đã giảm I/O bằng cách thay vì lấy toàn bộ dữ liệu bảng SALARY, EMPLOYEE ra để tiến hành JOIN sau đó mới lọc thì ta tiến hành lọc và lấy xác định các cột từ trước sau đó mới tiến hành JOIN vào với các điều kiện để lấy dữ liệu.
Đây chỉ là một ví dụ đơn giản để ta hiểu việc chỉ lấy dữ liệu cần thiết khi dùng thôi, còn thực tế thì phải tùy theo độ phức tạp để lấy dữ liệu một cách hiệu quả.