Với 13 triệu dữ liệu và 4Gb chúng tôi cải thiện tìm kiếm từ 6s còn 1s trong MYSQL không sử dụng ElasticSearch

Nội dung bài viết

Video học lập trình mỗi ngày

Bài viết này được đưa vào: Series: Tuần sau tôi đi phỏng vấn Backend

Series bao gồm nhiều câu hỏi phỏng vấn về cấp độ ngôn ngữ cũng như thiết kế hệ thống dành cho vị trí BackEnd. Nó phù hợp cho tất cả các level...

...

Kỹ năng này dành cho các công vừa và nhỏ. Và dành cho các lập trình ưa thích sự đơn giản, thích khám phá những dịch vụ có sẵn mà vẫn có thể giải quyết được công việc của mình với chí phí hầu như bằng 0 thay vì sử dụng một công nghệ khác có chi phí đắt đỏ hơn như chẳng hạn là ElasticSearch (3) Kỹ năng cần thiết sử dụng API REST.

Hãy xem kịch bản với 13 triệu dữ liệu chúng tôi tìm kiếm từ 6s còn 0.1s dưới đây và sau đó chúng tôi đã giải quyết vấn đề này.

Khuyến nghị: 10 triệu dữ liệu thì phân trang từ 7s còn 1s

Với 13 triệu dữ liệu, cải thiện tìm kiếm như thế nào?

Đây là một kịch bản có thật được thực hiện lại với một table (products) trong MySQL có 13 triệu dữ liệu.

Và có 3 tính huống tìm kiếm. Và mỗi tình huống có 3 cách, trong đó có 2 cách sử dụng toán tử LIKE = '%keySearch%'LIKE = 'keySearch%'. Như sau:

Nếu bạn không có thời gian, vui lòng xem thực nghiệm tại đây: Intern đánh bại Senior: Stop use LIKE trong việc SEARCH MYSQL chúng tôi đã cải thiện từ 6s còn 0.1s

Tình huống 1: Tìm "1969" là năm mà sản xuất được bao nhiêu chiếc xe?

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like '1969%'; -- 1.026s -> 104074 records

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like '%1969%'; -- 6.259 -> 104074 records

Như vậy không ổn chút nào đúng không? Có thấy sự khác biệt ở đây không?

Tình huống2: Bây giờ tìm những loại xe nào được Suzuki sản xuất?

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like 'Suzuki%'; -- notfound

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like '%Suzuki%'; -- 6.150 -> 1 records

Ở trường hợp này khi sử dụng like '%Suzuki%' thì nó tìm ra 1 record những mất tận 6.1s rất chậm chạp, ngoài ra khi sử dụng like 'Suzuki%'; thì lại tìm không ra?

Vì sao? Xem link giải thích ở đây về trường hợp này.

Tình huống 3. Bây giờ tìm những loại xe nào được Suzuki và Corsair sản xuất?

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like 'Suzuki Corsair%'; -- notfound

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like '%Suzuki Corsair%'; -- 6.150 -> 0 records

Xong luôn rồi, hai thằng đều không ra kết quả? Hãy yên tâm, chúng ta đã có cách sau khi đã phân tích các tình huống.

Cải thiện hiệu suất tìm kiếm trong MYSQL

  1. Tìm 1969 là năm mà sản xuất được bao nhiêu chiếc xe

Ta thấy có 3 trường hợp tìm kiếm nhưng cách 1 mất hơn 6s với 104074 records. Cách 2 mất hơn 1s và cùng số 104074 records. Cách 3 bí ẩn cũng mất hơn 1s cùng số 104074 records. Game hay bắt đầu. Vậy kịch bản đầu tiên với cùng trả về dữ liệu giống nhau nhưng cách 2 lại mất 6s. Và cách 1 và 2 thì lại tốt hơn. Lý do, là vì, khi dùng cách hai chú ý có hai '%%' và dữ liệu tìm kiếm được nằm chính giữa do vậy index ở đây sẽ không được áp dùng. Hãy xem phân tích với EXPLAIN. Bạn đã thấy ba cách thì cách 2 bị mất index. Scan toàn bộ dữ liệu với 13 triệu records..

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like '1969%'; -- 1.026s -> 104074 records

EXPLAIN
SELECT SQL_NO_CACHE * FROM products WHERE productName like '%1969%'; -- 6.259 -> 104074 records
  1. Bây giờ tìm những loại xe nào được Suzuki sản xuất:

...

Xem cách giải quyết bài toán này ở đây: Intern đánh bại Senior: Stop use LIKE trong việc SEARCH MYSQL chúng tôi đã cải thiện từ 6s còn 0.1s

Có thể bạn đã bị missing