SQL Performance: Tìm hiểu SELECT * và SELECT 1 column

4 min read

Mở đầu

SQL performance tuning là một nhiệm vụ cực kỳ khó khăn, đặc biệt là khi làm việc với dữ liệu lớn. Ở đó ngay cả một thay đổi nhỏ nhất cũng có thể có tác động mạnh mẽ (tích cực hoặc tiêu cực) đến performance.

SELECT là một trong những câu lệnh quen thuộc mà bất cứ ai có tìm hiểu về SQL đề sẽ biết, tuy nhiên biết thì chưa hẳn là đã thực sự hiểu về nó. Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu sâu hơn về SQL SELECT. So sánh sự khác nhau giữa SELECT * và SELECT 1 column. Không dài dòng nữa, bắt đầu thôi nào!

P/S: Ở bài viết này, mình sẽ đề cập đến một số khái niệm trong SQL performance tuning như execution plan, explain. Tuy nhiên mình sẽ không đi sâu vào giải thích những khái niệm này mà sẽ giải thích ở một bài viết khác. Mọi người hãy đón chờ nha!

SELECT * và SELECT 1 column có thực sự khác nhau?

Quá dễ! SELECT * thì trả về toàn bộ column của table. Còn SELECT 1 column thì sẽ trả về duy nhất 1 column được viết tên sau lệnh SELECT.

Đúng, nhưng chưa đủ. Còn về performance thì sao?

Do SELECT * trả về nhiều column hơn SELECT 1 column. Nên đương nhiên SELECT 1 column sẽ có performance tốt hơn rồi. Thế mà cũng phải hỏi…

Đúng, với SELECT * thì lượng dữ liệu trả về sẽ nhiều hơn SELECT 1 column. Do đó thời gian lấy kết quả của database sẽ lâu hơn. Nhưng đây chỉ là 1 yếu tố nhỏ nếu chúng ta nói về SQL performance. Yếu tố chính để đánh giá performance của một câu lệnh SELECT là execution plan của câu lệnh đó.

Execution plan đối với SELECT * và SELECT 1 column

Một lưu ý nhỏ trước khi bắt đầu. Nếu một câu lệnh có execution plan với cost càng nhỏ thì câu lệnh đó càng tối ưu về performance và ngược lại.

Ở đây mình sẽ sử dụng database là PostgreSqlpgadmin để thực hiện đánh giá execution plan.

Mình có một table tracked_indicator với 20k records và 16 column như hình bên dưới.

Đầu tiên mình sẽ kiểm tra execution plan của 2 câu lệnh.

Cả 2 câu lệnh SELECT đều có execution plan là sequence scan và cost là 996.63.

Cost càng nhỏ thì câu lệnh càng tối ưu. Vậy SELECT * và SELECT name có cost bằng nhau thì 2 câu lệnh này là như nhau à?

hmm…, cũng đúng. Chả nhẽ SELECT * và SELECT 1 column lại có performance như nhau….Gượm đã, bình thường có mấy khi SELECT mà lại không có điều kiện WHERE đâu, phải thử lại mới được.

Tiếp theo mình sẽ thực hiên SELECT với điều kiện WHERE trên column data_capture_frequency

Giống như vừa này, cả 2 câu lệnh đều có execution plan là sequence scan với cost là 1018.79 giống nhau. Vô lý thật, chả nhẽ SELECT * mà lại có performance ngang SELECT 1 column…. À đúng rồi, đã có điều kiện WHERE thì phải có index nữa chứ, thử lại lần nữa nào.

Tiếp tục là tạo index trên column data_capture_frequency. Sau đó thực hiện SELECT với điều kiện WHERE cũng trên colum data_capture_frequency

Đây rồi, cuối cùng cũng đã có sự khác biệt. Câu lệnh SELECT data_capture_frequency có execution plan là Index Only Scan và cost là 121.15. Trong khi đó, câu lệnh SELECT * lại là Bitmap Heap Scan với cost cao hơn nhiều: 846.15.

Vây là SELECT * có performance kém hơn SELECT 1 column trong trường hợp có điều kiện WHERE và có index. Nhưng vì sao nhỉ? Thế nếu SELECT 2, 3 column thôi thì sao?

Tiếp tục thử nghiệm với câu lệnh SELECT 2 column namedata_capture_frequency

Không phải là Index Only Scan mà là Bitmap Heap Scan với cost 846.15 tương tự như SELECT *. Thế nếu SELECT 1 column nhưng column đó lại không nằm trong index thì sao nhỉ?

Vẫn là Bitmap Heap Scan. Đến đây, chúng ta có thể đưa ra một kết luận là nếu câu lệnh SELECT có chứa column không thuộc điều kiện WHERE và không được đánh index thì sẽ có performance thấp hơn việc SELECT các column nằm trong điều kiện WHERE và có index

Vậy thì lý do là gì? Lý do ở đây là vì đối với câu lệnh SELECT những column nằm trong index thì database chỉ việc thực hiện index scan. Và trả lại kết quả luôn vì trong index đã có value của nhưng column đó. Tuy nhiên đối với câu lệnh SELECT những column không nằm trong index thì database ngoài việc thực hiện index scan thì phải look up qua table chính để có thể lấy được value của những column đó do không có value trong index.

Tổng kết

Trên đây là toàn bộ phần chia sẻ của mình, hi vọng rằng bài viết này sẽ giúp mọi người hiểu rõ hơn về câu lệnh SELECT trong SQL. Do mình chỉ mới nhập môn SQL Performance tuning gần đây nên có thể còn vẫn sai sót trong quá trình viết bài. Mọi người đừng ngần ngại mà để ngay comment phản hồi ở bên dưới bài viết nếu phát hiện ra sai sót nào nha. Cảm ơn và hẹn gặp lại mọi người trong những bài viết sau. See ya!

Tham khảo thêm về SQL Performance tuning ở đây

https://wecommit.com.vn/kien-thuc-huu-ich/

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *