3. Giới thiệu bản thân
• Tên: Phạm Văn Đông
• Công tác tại GMO Vietnamlab Center
• Các dự án đã thực hiện
– Angi, Quanlyca, EC, Big Data, Game Server
• Ngôn ngữ lập trình
– PHP, Java, Android, C#, Elixir, React, React
Native, GraphQL
• Database
– Mysql, SQL Server, Postgresql
3
4. Nội dung
1. Cơ bản về SQL & Tối ưu kiểu
2. Tối ưu sử dụng index
3. Tối ưu câu lệnh query
4. Tối ưu thiết kế bảng
5. Các kỹ thuật mới nâng cao hiệu năng
4
8. Cái DBMS phổ biến
• MySQL
• PostgreSQL
• SQL Server
• SQLite
• Big Data: Oracle, Hive, Google Big Query
8
9. Cú pháp SQL cơ bản
• Mệnh đề AND/OR trong SQL
9
SELECT cot1, cot2....cotN
FROM ten_bang
WHERE DIEU_KIEN_1 {AND|OR}
DIEU_KIEN_2;
10. Cú pháp SQL cơ bản
• Mệnh đề IN trong SQL
• Mệnh đề BETWEEN trong SQL
– BETWEEN: <, >, <= , >= ?
10
SELECT cot1, cot2....cotN
FROM ten_bang
WHERE ten_cot IN (gtri-1, gtri-2,...gtri-N);
SELECT cot1, cot2....cotN
FROM ten_bang
WHERE ten_cot BETWEEN gtri-1 AND gtri-
2;
11. Cú pháp SQL cơ bản
• Mệnh đề LIKE trong SQL
– PATTERN: GMO%, %runsystem, %run%
• Mệnh đề ORDER BY trong SQL
11
SELECT cot1, cot2....cotN
FROM ten_bang
WHERE ten_cot LIKE { PATTERN };
SELECT cot1, cot2....cotN
FROM ten_bang
WHERE DIEU_KIEN
ORDER BY ten_cot {ASC|DESC};
12. Cú pháp SQL cơ bản
• Mệnh đề GROUP BY trong SQL
• Ham số học
– SUM, MIN, MAX, AVG,
– Câu lệnh trên có đúng không?
12
SELECT SUM(ten_cot)
FROM ten_bang
WHERE DIEU_KIEN GROUP BY ten_cot;
SELECT COUNT(DISTINCT name)
FROM user;
13. Cú pháp SQL cơ bản
• Mệnh đề HAVING
• Diều kiền trong HAVING khác WHERE như
nào?
• HAVING hay WHERE nhanh hơn?
13
SELECT SUM(ten_cot)
FROM ten_bang
WHERE DIEU_KIEN GROUP BY ten_cot
HAVING (DIEU_KIEN);
14. Cú pháp SQL cơ bản
• Mệnh đề Joins trong SQL được sử dụng để kết hợp các
bản ghi từ hai hoặc nhiều bảng trong một Database.
14
SELECT bang1.cot1, bang2.cot2...
FROM bang1
LEFT JOIN bang2 ON bang1.field_chung =
bang2.field_chung;
15. Cú pháp SQL cơ bản
• EXPLAIN
15
EXPLAIN SELECT * FROM categoriesG
16. Cú pháp SQL cơ bản
16
mysql udbm02 c2> explain select * from user join user_detail on user.id = user_detail.user_id;
+------+-------------+-------------+--------+-----------------------------------+---------+---------+-------------
| id | select_type | table | type | possible_keys | key | key_len | ref
+------+-------------+-------------+--------+-----------------------------------+---------+---------+-------------
| 1 | SIMPLE | user_detail | ALL | user_detail_idx1,user_detail_idx2 | NULL | NULL | NULL
| 1 | SIMPLE | user | eq_ref | PRIMARY | PRIMARY | 4 | c2.user_deta
+------+-------------+-------------+--------+-----------------------------------+---------+---------+-------------
2 rows in set (0.00 sec)
mysql udbm02 c2> explain select * from user join user_detail on user.id = user_detail.user_id where user.id > 1000;
+------+-------------+-------------+-------+-----------------------------------+------------------+---------+----------
| id | select_type | table | type | possible_keys | key | key_len | ref
+------+-------------+-------------+-------+-----------------------------------+------------------+---------+----------
| 1 | SIMPLE | user | range | PRIMARY | PRIMARY | 4 | NULL
| 1 | SIMPLE | user_detail | ref | user_detail_idx1,user_detail_idx2 | user_detail_idx1 | 4 | c2.user.i
+------+-------------+-------------+-------+-----------------------------------+------------------+---------+----------
2 rows in set (0.00 sec)
17. Cú pháp SQL cơ bản
• EXPLAIN
– Đứng trước câu truy vấn
– Dùng để đưa thông tin thực hiện truy vấn
– Dựa vào thông tin này để khác phục về sự có
và hiệu năng
– Đặc biệt có ích trong điều tra nhưng câu SQL
phức tạp
17
18. Cú pháp SQL cơ bản
• id: Số thứ tự mỗi câu SELECT trong truy vấn
• select_type: Loại SELECT
– SIMPLE: truy vấn SELECT cơ bản không có truy vấn
con kể cả UNION
– PRIMARY: Là truy vấn ngoài cùng của lệnh JOIN
– DERIVED: Là truy vấn con của truy vấn khác
– SUBQUERY: Truy vấn đầu tiên của một truy vấn con
– DEPENDENT SUBQUERY: Truy vấn con, phụ thuộc
vào một truy vấn khác bên ngoài nó.
18
19. Cú pháp SQL cơ bản
• select_type
– UNION: Câu truy vấn thứ 2 của lệnh UNION
– DEPENDENT UNION: Truy vấn thứ hai hoặc các truy
vấn tiếp theo của lệnh UNION
– UNION RESULT: Truy vấn là kết quả của lệnh UNION
• table: Bảng liên quan đến câu truy vấn
19
20. Cú pháp SQL cơ bản
• type: Đây là trường quan trong nhất, nó
chỉ ra nơi thiếu index và làm thế nào để
sửa
– system: Bảng ko có hoặc chỉ có 1 dòng
– const: Bảng chỉ có 1 dòng duy nhất khớp với
điều kiện tìm kiếm
– eq_ref: các index được dụng để join và index
thuộc loại
20
21. Cú pháp SQL cơ bản
– ref: các cột đưa vào điều kiện tìm kiếm được đánh index
– ref_or_null: nhưng có cột mang giá trị null
– index_merge: sử dụng nhiều index trong điều kiện. Các
index hiển thị ở cột key
– unique_subquery: Truy vấn con với lệnh IN trả về kết
quả là khóa chính
– range: Các cột được đánh index được làm trong các
điều kiện BETWEEN, IN, >, >=,…
– index: Toàn bộ index được duyệt
– all: toàn bộ bản ghi
21
22. Cú pháp SQL cơ bản
• possible_keys: hiển thị toàn bộ key
• key: hiển thị key được sử dụng
• ref: tên cột được dùng để so sánh
• row: số lượng bản ghi được duyệt
• Extra: Các thông tin bỏ sung
Có thể thêm EXTENDED vào sau EXPLAIN
để xem them thông tin
22
23. Cú pháp SQL cở bản
• https://www.w3schools.com/SQL/default.a
sp
23
24. Kiểu dữ liệu
Kiểu dữ liệu Từ Tới
bigint -9,223,372,036,854,775,808 9,223,372,036,854,775,807
int -2,147,483,648 2,147,483,647
smallint -32,768 32,767
tinyint 0 255
bit 0 1
decimal -10^38 +1 10^38 -1
money -922,337,203,685,477.5808 +922,337,203,685,477.5807
smallmoney -214,748.3648 +214,748.3647
24
25. Kiểu dữ liệu
Kiểu dữ liệu Từ Tới
float -1.79E + 308 1.79E + 308
real -3.40E + 38 3.40E + 38
25
Kiểu dữ liệu Từ Tới
datetime 1000-01-01 9999-12-31
timestamp 1000-01-01 2038-01-19
26. Kiểu dữ liệu
26
Kiểu dữ liệu Max size
CHAR(n) 255 ký tự
VARCHAR(n) 255 ký tự > 255 sẽ chuyển về text
TINYTEXT 255 ký tự
TEXT 65,535ký tự
MEDIUMTEXT 16,777,215 ký tự
LONGTEXT 4,294,967,295 ký tự
ENUM(x,y,z,etc.) 65535 giá trị
27. Tối ứu kiểu dữ liệu
• Chọn kiểu dữ liệu phù hợp
• Số nguyên
• Số thực
• Kiểu chuỗi
• Tips
27
28. Chọn kiểu dữ liệu phù hợp
• Dữ liệu nhỏ
– Ít tốn bộ nhớ, ít tốn cache
• Đơn giản
– Ít tiêu tốn CPU hơn
– Ví dụ INT nhanh hơn STRING
• Tránh default Null
– Sẽ tốn bộ nhớ hơn bình thường, đặc biệt index
– Độ ưu tiên thấp
28
29. Số nguyên
• TINYINT, SMALLINT, MEDINUMINT, INT,
BIGINT yêu cầu 8, 16, 24, 32 và 64 bit lưu trữ
• UNSIGNED không cho phép giá trị âm
– Ví dụ TINYINT UNSIGNED có khoảng giá trị 0-255
thay vì -128 - 127
• Sign và Unsigned có không gian lưu trữ và hiệu
năng sử dụng là như nhau, tùy vào từng trường
hợp mà sử dụng cho hợp lý.
29
30. Số thực
• Kiểu FLOAT và DOUBLE hỗ trợ tính toán gần
đúng với tiêu chuẩn dấu phẩy động.
• Kiểu DECIMAL để lưu trữ số thập phân chính
xác.
• Chỉ sử dụng DECIMAL khi cần kết quả số liệu
chính xác.
30
31. Kiểu chuỗi
• VARCHAR
– Chuỗi có độ dài nhỏ hơn giá trị cho trước
– Sử dụng 1byte cho 255 ký tự
– Với ký tự latin varchar(10) sử dụng 11byte,
varchar(1000) sử dụng 1002 byte.
– Cần phải chọn độ dài hợp lý
– Trường hợp quá độ dài nếu là MyISAM có thể
phân mảnh row, InnoDB có thể chia nhỏ page
để vừa row
31
32. Kiểu chuỗi
• CHAR
– Char là kiểu fixed length
– Nên sử dụng với các chuỗi fixed length như MD5
• BLOB và TEXT
– Xử lý như 1 đối tượng
– BLOB lưu theo kiểu nhị phân nên ko cần charset
– Không đánh index được
– Không sort được theo full length
32
33. Kiểu chuỗi
• DATETIME
– Năm từ 1001 -> 9999
– Độ chính xác hàng s.
– Dữ liệu của nó đc đóng gói vào int
YYYYMMDDHHMMSS format,
– Sử dụng 8byte lưu trữ.
– Có thể sort đc.
33
34. Kiểu chuỗi
• TIMESTAMP
– store theo dạng tổng số giây.
– Chỉ có 4 byte lưu trữ. 1970 -> 2038.
– Tự insert/update theo timezone
– Không được phép null
34
35. Kiểu chuỗi
• ENUM
– Lưu một tập các giá trị chuỗi
– Được đóng gới vào 1 hoặc 2 byte tùy vào số
lượng
– ORDER BY FIELD(e, 'apple', 'dog', 'fish');
– Dánh sách cố định không thêm được, phải
alter table
35
36. Kiểu chuỗi
Test Queries per second
VARCHAR joined to VARCHAR 2.6
VARCHAR joined to ENUM 1.7
ENUM joined to VARCHAR 1.8
ENUM joined to ENUM 3.5
36
37. Tips
• Sử dụng int cho các chỉ mục số
• Cẩn thận với random string, ví dụ như các hàm
hashcode. Làm chậm và khó index
• Hạn chế nhiều cột một bảng
– Mysql storage engine lấy các bản ghi qua row buffer
– Server decode buffer trong column
– Chắc chắn làm tang CPU
• Không nên dùng nhiều join
37
38. Tips
• Tráng sử dụng NULL
• Sử dụng cùng kiểu dữ liệu với những loại
dữ liệu tương tự nhau. Để join dễ hơn.
• Cẩn thận variable-length của string.
• Cận thận với ENUM
38
39. Tips
• Chỉ select nhưng cột cần thiết
• Nên sử dụng EXISTS() để kiểm tra truy vấn có trả về dữ
liệu không
• Tránh dung HAVING
39