SlideShare a Scribd company logo
1
Training SQL
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
2
• Tại sao query lại chậm?
• Tối ưu truy vấn dài
• Tối ưu kết hợp nhiều query
• Tối ưu COUNT() query
• Tối ưu GROUP BY và DISTINCT
• Tối ưu LIMIT và OFFSET
• Tối ưu UNION
• Tối ưu MIN và MAX
3
4
Tại sao query lại chậm?
Tại sao query lại chậm?
5
Tại sao query lại chậm?
• Tốn quá nhiều bộ nhớ
• Tốn quá nhiều CPU xử lý
• Network chậm
• Quá nhiều query sử lý cùng 1 lúc
6
Tối ưu truy vấn dài
• Lấy toàn bộ tên diễn viên trong bộ phim
Academy Dinosaur
7
mysql> SELECT * FROM actor
-> INNER JOIN film_actor USING(actor_id)
-> INNER JOIN film USING(film_id)
-> WHERE film.title = 'Academy Dinosaur';
Tối ưu truy vấn dài
• Viết lại
8
mysql> SELECT actor.* FROM actor...;
9
Tối ưu truy vấn dài
Tối ưu truy vấn dài
• Trường hợp bắt buộc phải lấy tất cả phải làm
thế nào?
10
mysql> SELECT * FROM actor
-> INNER JOIN film_actor USING(actor_id)
-> INNER JOIN film USING(film_id)
-> WHERE film.title = 'Academy Dinosaur';
Tối ưu truy vấn dài
11
SELECT * FROM tag WHERE tag='mysql';
SELECT * FROM tag_post WHERE tag_id=1234;
SELECT * FROM post WHERE post.id in (123,456,567,9098);
Tối ưu truy vấn dài
• Việc caching dữ liệu sẽ hiệu quả hơn
• Thực hiện lần lượt các câu lệnh tránh việc lock
tài nguyên
• Lấy ra kết quả sẽ dễ dàng hơn trong trường hợp
đặt database tại nhiều server
• Giảm thiểu số lượng các dòng dữ liệu phải kiểm
tra
12
Tối ưu truy vấn dài
• Câu truy vấn sau bị chậm do thực hiện
xóa hàng triệu bản ghi
13
mysql> DELETE FROM messages
-> WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH);
Tối ưu truy vấn dài
14
rows_affected = 0
do {
rows_affected = do_query(
"DELETE FROM messages
WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH)
LIMIT 10000")
} while rows_affected > 0
15
Tối ưu kết hợp nhiều query
Tối ưu kết hợp nhiều query
• Lấy tất cả film của actor = 1
16
SELECT * FROM sakila.film
WHERE film_id IN(
SELECT film_id
FROM sakila.film_actor
WHERE actor_id = 1
);
Tối ưu kết hợp nhiều query
• Lấy tất cả film của actor = 1
17
SELECT * FROM sakila.film
WHERE EXISTS(
SELECT film_id
FROM sakila.film_actor
WHERE actor_id = 1
AND film_actor.film_id = film.film_id
);
+----+--------------------+------------+--------+------------------------+
| id | select_type | table | type | possible_keys |
+----+--------------------+------------+--------+------------------------+
| 1 | PRIMARY | film | ALL | NULL |
| 2 | DEPENDENT SUBQUERY | film_actor | eq_ref | PRIMARY,idx_fk_film_id |
+----+--------------------+------------+--------+------------------------+
Tối ưu kết hợp nhiều query
• Có thể sử dụng JOIN
18
SELECT DISTINCT film.id FROM sakila.film
INNER JOIN sakila.film_actor USING(film_id);
Query Kết quả queries per second (QPS)
INNER JOIN 185 QPS
EXISTS subquery 325 QPS
SELECT film_id FROM sakila.film
WHERE EXISTS(SELECT * FROM sakila.film_actor
WHERE film.film_id = film_actor.film_id);
Tối ưu kết hợp nhiều query
• Trường hợp ngược lại
19
SELECT film_id, language_id FROM sakila.film
WHERE NOT EXISTS(
SELECT * FROM sakila.film_actor
WHERE film_actor.film_id = film.film_id
)
SELECT film.film_id, film.language_id
FROM sakila.film
LEFT OUTER JOIN sakila.film_actor USING(film_id)
WHERE film_actor.film_id IS NULL
Tối ưu kết hợp nhiều query
20
Query Kết quả queries per second (QPS)
NOT EXISTS subquery 360 QPS
LEFT OUTER JOIN 425 QPS
21
Tối ưu COUNT() query
Tối ưu COUNT() query
• COUNT(col) và COUNT(*) khác nhau như
nào?
22
Tối ưu COUNT() query
• Count([col]) đếm số lần cột có giá trị khác NULL
• Count(*) không quan tâm đến cột, và chỉ đếm số
dòng kết quả trả về
23
Tối ưu COUNT() query
• Bảng 'goods_item' có 20.000 bản ghi với
cột id là khóa chính tự tăng.
• Có bao nhiêu bản ghi có id > 5?
24
id code name
1 0000001 sp1
... ... ...
20000 0020000 sp20000
Tối ưu COUNT() query
• Mất 0.012s
• EXPLAIN
25
Select COUNT(*) From goods_item Where id > 5;
id select_type type key rows Extra
1 PRIMARY range PRIMARY 9932 Using where; Using
index
Tối ưu COUNT() query
• Query được tối ưu như sau:
• Mất 0.007s
26
Select (Select Count(*) From goods_item) - Count(*)
From goods_item
Where id <= 5;
id select_type table rows Extra
1 PRIMARY goods_item 6 Using where; Using index
2 SUBQUERY NULL NULL Select tables optimized away
Tối ưu COUNT() query
• Câu query này lấy count chỉ sử dụng index
– Select Count(*) From goods_item
• Chỉ tìm ở nhánh <= 5
– Where id <= 5;
27
Tối ưu COUNT() query
• Lấy count của color là blue và red
• Làm thế nào để lấy count của của từng
color chỉ trong 1 query
28
SELECT COUNT(color = 'blue' OR color = 'red')
FROM items
Tối ưu COUNT() query
29
SELECT COUNT(color = 'blue' OR NULL) AS blue,
COUNT(color = 'red' OR NULL) AS red
FROM items;
SELECT SUM(IF(color = 'blue', 1, 0)) AS blue,
SUM(IF(color = 'red', 1, 0)) AS red
FROM items;
30
Tối ưu GROUP BY và
DISTINCT
Tối ưu GROUP BY và DISTINCT
• Query 1
• Query 2
31
Select actor.first_name, actor.last_name, COUNT(*)
From sakila.film_actor
Inner JOIN sakila.actor USING(actor_id)
GROUP BY actor.first_name, actor.last_name;
Select actor.first_name, actor.last_name, COUNT(*)
From sakila.film_actor
Inner JOIN sakila.actor USING(actor_id)
GROUP BY actor.actor_id;
Tối ưu GROUP BY và DISTINCT
• Nếu như first_name và last_name là unique thì
Query 2 nhanh hơn
• Tuy nhiên phải duyệt hết kết quả để count
32
Select actor.first_name, actor.last_name, COUNT(*)
From sakila.film_actor
Inner JOIN sakila.actor USING(actor_id)
GROUP BY actor.actor_id;
Tối ưu GROUP BY và DISTINCT
33
SELECT actor.first_name, actor.last_name, c.cnt
FROM sakila.actor
INNER JOIN (
SELECT actor_id, COUNT(*) AS cnt
FROM sakila.film_actor
GROUP BY actor_id
) AS c USING(actor_id) ;
Tối ưu GROUP BY và DISTINCT
• GROUP BY sẽ tự order
34
Select * From
(Select * From
(Select A.actor_id, A.first_name, A.last_name, F.release_year
From actor A
Inner join film_actor FA Using(actor_id)
Inner join film F On FA.film_id = F.film_id
Order by A.first_name, A.last_name, F.release_year desc
) actor
GROUP BY actor.actor_id
-- Sau khi GROUP BY sẽ tự động sort theo actor.actor_id.
) actor2
-- Phải sort lại một lần nữa.
ORDER BY actor2.first_name, actor2.last_name, actor2.release_year desc;
Tối ưu GROUP BY và DISTINCT
• Thêm ORDER BY NULL để skip sort
35
Select * From
(Select A.actor_id, A.first_name, A.last_name, F.release_year
From actor A
Inner join film_actor FA Using(actor_id)
Inner join film F On FA.film_id = F.film_id
Order by A.first_name, A.last_name, F.release_year desc
) actor
GROUP BY actor.actor_id
ORDER BY NULL
36
Tối ưu LIMIT và OFFSET
Tối ưu LIMIT và OFFSET
• Sử dụng cho bảng duyệt nhiều bản ghi và kết
quả trả về ít
37
SELECT <cols> FROM profiles INNER JOIN (
SELECT <primary key cols> FROM profiles
WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
) AS x USING(<primary key cols>);
Tối ưu LIMIT và OFFSET
• Sử dụng điều kiện với id để giới hạn bản ghi
• Lấy bản ghi từ 16049 quay về 16030
• 20 bản ghi tiếp theo
38
mysql> SELECT * FROM sakila.rental
-> WHERE rental_id < 16030
-> ORDER BY rental_id DESC LIMIT 20;
mysql> SELECT * FROM sakila.rental
-> ORDER BY rental_id DESC LIMIT 20;
39
Tối ưu UNION
Tối ưu UNION
• Câu query tối ưu chưa
40
(SELECT first_name, last_name
FROM sakila.actor
ORDER BY last_name)
UNION ALL
(SELECT first_name, last_name
FROM sakila.customer
ORDER BY last_name)
LIMIT 20;
Tối ưu UNION
41
(SELECT first_name, last_name
FROM sakila.actor
ORDER BY last_name
LIMIT 20)
UNION ALL
(SELECT first_name, last_name
FROM sakila.customer
ORDER BY last_name
LIMIT 20)
LIMIT 20;
42
Tối ưu MIN và MAX
Tối ưu MIN và MAX
• Lấy MIN actor, không có index cho first_name
43
SELECT MIN(actor_id)
FROM sakila.actor
WHERE first_name = 'PENELOPE';
Tối ưu MIN và MAX
44
SELECT actor_id
FROM sakila.actor USE INDEX(PRIMARY)
WHERE first_name = 'PENELOPE‘
LIMIT 1;
Tổng hợp
• Đảm bảo các query đơn giản nếu có thể
– Có thẻ cache
– Cũng không nên chia quá nhiều query
• Trong các trường hợp nhiều bản ghi hãy chủ ý
sử dụng LIMIT hiệu quả
• Đảm bảo rằng các cột trong điều kiện join ON,
USING phải được đánh index
• Cố gắngGROUP BY, ORDER BY một lần
45
Tổng hợp
• Luôn sử dụng EXPLAIN để điều tra câu query
• UPDATE version mới nhất cho RDBMS
46

More Related Content

What's hot

csdl bai-thuchanh_01
csdl bai-thuchanh_01csdl bai-thuchanh_01
csdl bai-thuchanh_01
kikihoho
 
Cursor & Function trong SQL Server
Cursor & Function trong SQL ServerCursor & Function trong SQL Server
Cursor & Function trong SQL Server
Huy Vũ
 
BÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPT
BÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPTBÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPT
BÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPT
MasterCode.vn
 
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEW
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEWSlide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEW
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEW
pisu412
 
Bài 2: Biến và toán tử - Giáo trình FPT
Bài 2: Biến và toán tử - Giáo trình FPTBài 2: Biến và toán tử - Giáo trình FPT
Bài 2: Biến và toán tử - Giáo trình FPT
MasterCode.vn
 
csdl bai-thuchanh_02
csdl bai-thuchanh_02csdl bai-thuchanh_02
csdl bai-thuchanh_02
kikihoho
 
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3
pisu412
 
04 chuong 4 - cap nhat du lieu
04   chuong 4 - cap nhat du lieu04   chuong 4 - cap nhat du lieu
04 chuong 4 - cap nhat du lieu
truong le hung
 
04 chuong 4 - sap xep, tim kiem, loc du lieu
04   chuong 4 - sap xep, tim kiem, loc du lieu04   chuong 4 - sap xep, tim kiem, loc du lieu
04 chuong 4 - sap xep, tim kiem, loc du lieutruong le hung
 
Bài 2 : Các đối tượng trong CSDL - SQL server
Bài 2 : Các đối tượng trong CSDL - SQL serverBài 2 : Các đối tượng trong CSDL - SQL server
Bài 2 : Các đối tượng trong CSDL - SQL server
MasterCode.vn
 
Slide create databases_linh
Slide create databases_linhSlide create databases_linh
Slide create databases_linhkhacthuong2008
 

What's hot (11)

csdl bai-thuchanh_01
csdl bai-thuchanh_01csdl bai-thuchanh_01
csdl bai-thuchanh_01
 
Cursor & Function trong SQL Server
Cursor & Function trong SQL ServerCursor & Function trong SQL Server
Cursor & Function trong SQL Server
 
BÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPT
BÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPTBÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPT
BÀI 6: Thủ tục (SUB) và hàm (FUNCTION) - Giáo trình FPT
 
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEW
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEWSlide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEW
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3 VIEW
 
Bài 2: Biến và toán tử - Giáo trình FPT
Bài 2: Biến và toán tử - Giáo trình FPTBài 2: Biến và toán tử - Giáo trình FPT
Bài 2: Biến và toán tử - Giáo trình FPT
 
csdl bai-thuchanh_02
csdl bai-thuchanh_02csdl bai-thuchanh_02
csdl bai-thuchanh_02
 
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3
Slide Hệ Quản Trị Cơ sở dữ liệu - CHƯƠNG 3
 
04 chuong 4 - cap nhat du lieu
04   chuong 4 - cap nhat du lieu04   chuong 4 - cap nhat du lieu
04 chuong 4 - cap nhat du lieu
 
04 chuong 4 - sap xep, tim kiem, loc du lieu
04   chuong 4 - sap xep, tim kiem, loc du lieu04   chuong 4 - sap xep, tim kiem, loc du lieu
04 chuong 4 - sap xep, tim kiem, loc du lieu
 
Bài 2 : Các đối tượng trong CSDL - SQL server
Bài 2 : Các đối tượng trong CSDL - SQL serverBài 2 : Các đối tượng trong CSDL - SQL server
Bài 2 : Các đối tượng trong CSDL - SQL server
 
Slide create databases_linh
Slide create databases_linhSlide create databases_linh
Slide create databases_linh
 

More from Đông Đô

Maria db spider engine
Maria db spider engineMaria db spider engine
Maria db spider engine
Đông Đô
 
Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...
Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...
Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...
Đông Đô
 
Daily scrum
Daily scrumDaily scrum
Daily scrum
Đông Đô
 
He thong chiu tai cao
He thong chiu tai caoHe thong chiu tai cao
He thong chiu tai cao
Đông Đô
 
TDD (Test Driven Development)
TDD (Test Driven Development)TDD (Test Driven Development)
TDD (Test Driven Development)
Đông Đô
 
Pair programing
Pair programingPair programing
Pair programing
Đông Đô
 
The Art of Readable Code - DongPV
The Art of Readable Code - DongPVThe Art of Readable Code - DongPV
The Art of Readable Code - DongPV
Đông Đô
 

More from Đông Đô (7)

Maria db spider engine
Maria db spider engineMaria db spider engine
Maria db spider engine
 
Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...
Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...
Xây dụng và kết hợp Kafka, Druid, Superset để đua vào ứng dụng phân tích dữ l...
 
Daily scrum
Daily scrumDaily scrum
Daily scrum
 
He thong chiu tai cao
He thong chiu tai caoHe thong chiu tai cao
He thong chiu tai cao
 
TDD (Test Driven Development)
TDD (Test Driven Development)TDD (Test Driven Development)
TDD (Test Driven Development)
 
Pair programing
Pair programingPair programing
Pair programing
 
The Art of Readable Code - DongPV
The Art of Readable Code - DongPVThe Art of Readable Code - DongPV
The Art of Readable Code - DongPV
 

Training sql3

  • 2. 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 2
  • 3. • Tại sao query lại chậm? • Tối ưu truy vấn dài • Tối ưu kết hợp nhiều query • Tối ưu COUNT() query • Tối ưu GROUP BY và DISTINCT • Tối ưu LIMIT và OFFSET • Tối ưu UNION • Tối ưu MIN và MAX 3
  • 4. 4 Tại sao query lại chậm?
  • 5. Tại sao query lại chậm? 5
  • 6. Tại sao query lại chậm? • Tốn quá nhiều bộ nhớ • Tốn quá nhiều CPU xử lý • Network chậm • Quá nhiều query sử lý cùng 1 lúc 6
  • 7. Tối ưu truy vấn dài • Lấy toàn bộ tên diễn viên trong bộ phim Academy Dinosaur 7 mysql> SELECT * FROM actor -> INNER JOIN film_actor USING(actor_id) -> INNER JOIN film USING(film_id) -> WHERE film.title = 'Academy Dinosaur';
  • 8. Tối ưu truy vấn dài • Viết lại 8 mysql> SELECT actor.* FROM actor...;
  • 9. 9 Tối ưu truy vấn dài
  • 10. Tối ưu truy vấn dài • Trường hợp bắt buộc phải lấy tất cả phải làm thế nào? 10 mysql> SELECT * FROM actor -> INNER JOIN film_actor USING(actor_id) -> INNER JOIN film USING(film_id) -> WHERE film.title = 'Academy Dinosaur';
  • 11. Tối ưu truy vấn dài 11 SELECT * FROM tag WHERE tag='mysql'; SELECT * FROM tag_post WHERE tag_id=1234; SELECT * FROM post WHERE post.id in (123,456,567,9098);
  • 12. Tối ưu truy vấn dài • Việc caching dữ liệu sẽ hiệu quả hơn • Thực hiện lần lượt các câu lệnh tránh việc lock tài nguyên • Lấy ra kết quả sẽ dễ dàng hơn trong trường hợp đặt database tại nhiều server • Giảm thiểu số lượng các dòng dữ liệu phải kiểm tra 12
  • 13. Tối ưu truy vấn dài • Câu truy vấn sau bị chậm do thực hiện xóa hàng triệu bản ghi 13 mysql> DELETE FROM messages -> WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH);
  • 14. Tối ưu truy vấn dài 14 rows_affected = 0 do { rows_affected = do_query( "DELETE FROM messages WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH) LIMIT 10000") } while rows_affected > 0
  • 15. 15 Tối ưu kết hợp nhiều query
  • 16. Tối ưu kết hợp nhiều query • Lấy tất cả film của actor = 1 16 SELECT * FROM sakila.film WHERE film_id IN( SELECT film_id FROM sakila.film_actor WHERE actor_id = 1 );
  • 17. Tối ưu kết hợp nhiều query • Lấy tất cả film của actor = 1 17 SELECT * FROM sakila.film WHERE EXISTS( SELECT film_id FROM sakila.film_actor WHERE actor_id = 1 AND film_actor.film_id = film.film_id ); +----+--------------------+------------+--------+------------------------+ | id | select_type | table | type | possible_keys | +----+--------------------+------------+--------+------------------------+ | 1 | PRIMARY | film | ALL | NULL | | 2 | DEPENDENT SUBQUERY | film_actor | eq_ref | PRIMARY,idx_fk_film_id | +----+--------------------+------------+--------+------------------------+
  • 18. Tối ưu kết hợp nhiều query • Có thể sử dụng JOIN 18 SELECT DISTINCT film.id FROM sakila.film INNER JOIN sakila.film_actor USING(film_id); Query Kết quả queries per second (QPS) INNER JOIN 185 QPS EXISTS subquery 325 QPS SELECT film_id FROM sakila.film WHERE EXISTS(SELECT * FROM sakila.film_actor WHERE film.film_id = film_actor.film_id);
  • 19. Tối ưu kết hợp nhiều query • Trường hợp ngược lại 19 SELECT film_id, language_id FROM sakila.film WHERE NOT EXISTS( SELECT * FROM sakila.film_actor WHERE film_actor.film_id = film.film_id ) SELECT film.film_id, film.language_id FROM sakila.film LEFT OUTER JOIN sakila.film_actor USING(film_id) WHERE film_actor.film_id IS NULL
  • 20. Tối ưu kết hợp nhiều query 20 Query Kết quả queries per second (QPS) NOT EXISTS subquery 360 QPS LEFT OUTER JOIN 425 QPS
  • 22. Tối ưu COUNT() query • COUNT(col) và COUNT(*) khác nhau như nào? 22
  • 23. Tối ưu COUNT() query • Count([col]) đếm số lần cột có giá trị khác NULL • Count(*) không quan tâm đến cột, và chỉ đếm số dòng kết quả trả về 23
  • 24. Tối ưu COUNT() query • Bảng 'goods_item' có 20.000 bản ghi với cột id là khóa chính tự tăng. • Có bao nhiêu bản ghi có id > 5? 24 id code name 1 0000001 sp1 ... ... ... 20000 0020000 sp20000
  • 25. Tối ưu COUNT() query • Mất 0.012s • EXPLAIN 25 Select COUNT(*) From goods_item Where id > 5; id select_type type key rows Extra 1 PRIMARY range PRIMARY 9932 Using where; Using index
  • 26. Tối ưu COUNT() query • Query được tối ưu như sau: • Mất 0.007s 26 Select (Select Count(*) From goods_item) - Count(*) From goods_item Where id <= 5; id select_type table rows Extra 1 PRIMARY goods_item 6 Using where; Using index 2 SUBQUERY NULL NULL Select tables optimized away
  • 27. Tối ưu COUNT() query • Câu query này lấy count chỉ sử dụng index – Select Count(*) From goods_item • Chỉ tìm ở nhánh <= 5 – Where id <= 5; 27
  • 28. Tối ưu COUNT() query • Lấy count của color là blue và red • Làm thế nào để lấy count của của từng color chỉ trong 1 query 28 SELECT COUNT(color = 'blue' OR color = 'red') FROM items
  • 29. Tối ưu COUNT() query 29 SELECT COUNT(color = 'blue' OR NULL) AS blue, COUNT(color = 'red' OR NULL) AS red FROM items; SELECT SUM(IF(color = 'blue', 1, 0)) AS blue, SUM(IF(color = 'red', 1, 0)) AS red FROM items;
  • 30. 30 Tối ưu GROUP BY và DISTINCT
  • 31. Tối ưu GROUP BY và DISTINCT • Query 1 • Query 2 31 Select actor.first_name, actor.last_name, COUNT(*) From sakila.film_actor Inner JOIN sakila.actor USING(actor_id) GROUP BY actor.first_name, actor.last_name; Select actor.first_name, actor.last_name, COUNT(*) From sakila.film_actor Inner JOIN sakila.actor USING(actor_id) GROUP BY actor.actor_id;
  • 32. Tối ưu GROUP BY và DISTINCT • Nếu như first_name và last_name là unique thì Query 2 nhanh hơn • Tuy nhiên phải duyệt hết kết quả để count 32 Select actor.first_name, actor.last_name, COUNT(*) From sakila.film_actor Inner JOIN sakila.actor USING(actor_id) GROUP BY actor.actor_id;
  • 33. Tối ưu GROUP BY và DISTINCT 33 SELECT actor.first_name, actor.last_name, c.cnt FROM sakila.actor INNER JOIN ( SELECT actor_id, COUNT(*) AS cnt FROM sakila.film_actor GROUP BY actor_id ) AS c USING(actor_id) ;
  • 34. Tối ưu GROUP BY và DISTINCT • GROUP BY sẽ tự order 34 Select * From (Select * From (Select A.actor_id, A.first_name, A.last_name, F.release_year From actor A Inner join film_actor FA Using(actor_id) Inner join film F On FA.film_id = F.film_id Order by A.first_name, A.last_name, F.release_year desc ) actor GROUP BY actor.actor_id -- Sau khi GROUP BY sẽ tự động sort theo actor.actor_id. ) actor2 -- Phải sort lại một lần nữa. ORDER BY actor2.first_name, actor2.last_name, actor2.release_year desc;
  • 35. Tối ưu GROUP BY và DISTINCT • Thêm ORDER BY NULL để skip sort 35 Select * From (Select A.actor_id, A.first_name, A.last_name, F.release_year From actor A Inner join film_actor FA Using(actor_id) Inner join film F On FA.film_id = F.film_id Order by A.first_name, A.last_name, F.release_year desc ) actor GROUP BY actor.actor_id ORDER BY NULL
  • 36. 36 Tối ưu LIMIT và OFFSET
  • 37. Tối ưu LIMIT và OFFSET • Sử dụng cho bảng duyệt nhiều bản ghi và kết quả trả về ít 37 SELECT <cols> FROM profiles INNER JOIN ( SELECT <primary key cols> FROM profiles WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10 ) AS x USING(<primary key cols>);
  • 38. Tối ưu LIMIT và OFFSET • Sử dụng điều kiện với id để giới hạn bản ghi • Lấy bản ghi từ 16049 quay về 16030 • 20 bản ghi tiếp theo 38 mysql> SELECT * FROM sakila.rental -> WHERE rental_id < 16030 -> ORDER BY rental_id DESC LIMIT 20; mysql> SELECT * FROM sakila.rental -> ORDER BY rental_id DESC LIMIT 20;
  • 40. Tối ưu UNION • Câu query tối ưu chưa 40 (SELECT first_name, last_name FROM sakila.actor ORDER BY last_name) UNION ALL (SELECT first_name, last_name FROM sakila.customer ORDER BY last_name) LIMIT 20;
  • 41. Tối ưu UNION 41 (SELECT first_name, last_name FROM sakila.actor ORDER BY last_name LIMIT 20) UNION ALL (SELECT first_name, last_name FROM sakila.customer ORDER BY last_name LIMIT 20) LIMIT 20;
  • 42. 42 Tối ưu MIN và MAX
  • 43. Tối ưu MIN và MAX • Lấy MIN actor, không có index cho first_name 43 SELECT MIN(actor_id) FROM sakila.actor WHERE first_name = 'PENELOPE';
  • 44. Tối ưu MIN và MAX 44 SELECT actor_id FROM sakila.actor USE INDEX(PRIMARY) WHERE first_name = 'PENELOPE‘ LIMIT 1;
  • 45. Tổng hợp • Đảm bảo các query đơn giản nếu có thể – Có thẻ cache – Cũng không nên chia quá nhiều query • Trong các trường hợp nhiều bản ghi hãy chủ ý sử dụng LIMIT hiệu quả • Đảm bảo rằng các cột trong điều kiện join ON, USING phải được đánh index • Cố gắngGROUP BY, ORDER BY một lần 45
  • 46. Tổng hợp • Luôn sử dụng EXPLAIN để điều tra câu query • UPDATE version mới nhất cho RDBMS 46