- vừa được xem lúc

12 lý do khiến MySQL truy vấn chậm - Part 1

0 0 16

Người đăng: Huỳnh Phúc Vương

Theo Viblo Asia

1. SQL không được đánh index

Nhiều lần, truy vấn chậm của chúng ta là do không có index . Nếu không có index, nó sẽ gây ra quá trình quét toàn bộ bảng. Do đó, bạn nên xem xét khi truy vấn các cột có điều kiện, xây dựng chỉ mục và cố gắng tránh quét toàn bộ bảng.

Câu lệnh bắt đầu bằng EXPLAIN trong hình trên là để lấy thông tin về cách MariaDB thực hiện một SELECT, UPDATE hoặc DELETE. Nhìn vào cột type bạn sẽ thấy nó có giá trị là ALL. Có nghĩa là nó đang quét toàn bộ bảng điều này là không nên đối với các bảng lớn. Ngoài ra còn một số type khác bạn có thể xem ở hình sau:

Trường hợp lí tưởng chúng ta sẽ làm như sau:

// đánh index
alter table users add index idx_name (name);

bây giời nhìn vào hình trên cột type đã chuyển thành giá trị ref. Để biết giá trị ref có ý nghĩa gì các bạn có thể xem trong phần type mình có chia sẻ ở trên.

2. Index không có hiệu lực

Đôi khi chúng ta rõ ràng thêm index, nhưng index đó không có hiệu lực. Vậy index sẽ không có hiệu lực trong các trường hợp nào?

2.1 Sử dụng điều kiện truy vấn khác kiểu dữ liệu

Chúng ta tạo một bảng users như sau

CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, user_id varchar(32) NOT NULL, age varchar(16) NOT NULL, name varchar(255) NOT NULL, PRIMARY KEY (id), KEY idx_user_id (user_id) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Trường user_id là một kiểu chuỗi và là index chung của B+ tree. Nếu một số được sử dụng trong điều kiện truy vấn index sẽ không có hiệu lực như hình sau:

2.2 Điều kiện truy vấn chứa OR, có thể khiến index bị lỗi

Chúng ta vẫn sử dụng cấu trúc bảng như trên

CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, user_id varchar(32) NOT NULL, age varchar(16) NOT NULL, name varchar(255) NOT NULL, PRIMARY KEY (id), KEY idx_user_id (user_id) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Trường user_id được đánh index, nhưng age không được đánh index. Chúng ta sử dụng kết hợp với OR và cho kết quả như sau: Đối với truy vấn OR trường hợp age không được đánh index, giả sử rằng nó đã chuyển đến index của user_id , nhưng khi đến điều kiện try vấn age, nó phải thực hiện quét toàn bộ bảng, tức là quy trình ba bước được yêu cầu: quét toàn bộ bảng + quét index + hợp nhất . Nếu nó quét toàn bộ bảng ngay từ đầu , nó sẽ được thực hiện bằng một lần quét. Vì để tối ưu trong trường hợp này, trình tối ưu hóa Mysql gặp phải các điều kiện OR nó sẽ không sử dụng index, điều này có vẻ hợp lý.

Lưu ý : Nếu tất cả các trường của điều kiện OR đều được đánh index, thì chỉ mục có thể được sử dụng hoặc không , bạn có thể tự mình thử. Nhưng khi sử dụng, bạn vẫn phải chú ý điều kiện này và sử dụng explain phân tích. Khi gặp trường hợp tương tự, hãy xem xét tách hai SQL.

2.3. Như các ký tự đặc biệt có thể làm cho index không có hiệu lực

Không phải là sử dụng like + ký tự đặc biệt index sẽ không hợp lệ, nhưng truy vấn tương tự bắt đầu bằng % sẽ khiến index bị lỗi. % đặt lại ở cuối thì thấy index vẫn chạy bình thường, cụ thể như sau:

2.4. Điều kiện truy vấn không đáp ứng nguyên tắc leftmost prefix của index chung

Khi MySQl tạo một index chung, nó sẽ tuân theo nguyên tắc leftmost prefix, tức là index sẽ được sử dụng để tìm kiếm các bản ghi dựa trên giá trị của các trường từ trái sang phải. Nếu bạn tạo một(a,b,c)chỉ mục chung, nó tương đương với việc tạo (a), (a,b), (a,b,c) ba chỉ mục. Giả sử bạn có cấu trúc bảng sau:

CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, user_id varchar(32) NOT NULL, age varchar(16) NOT NULL, name varchar(255) NOT NULL, PRIMARY KEY (id), KEY idx_userid_name (user_id,name) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Có một chỉ mục chung idx_userid_name, chúng ta thực thi SQL này, điều kiện truy vấn là name index không hợp lệ:

Bởi vì cột điều kiện truy vấn name không phải là idx_userid_name cột đầu tiên trong index chung, index không có hiệu lực Trong một index chung, index chỉ có hiệu lực khi các điều kiện truy vấn thỏa mãn leftmost prefix.

2.5. Sử dụng các hàm tích hợp của MySQL trên các cột được đánh index

Cấu trúc bảng:

CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT,user_id varchar(32) NOT NULL,login_time datetime NOT NULL, PRIMARY KEY (id ), KEY idx_userId (user_id ) USING BTREE, KEY idx_login_time (login_Time) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Mặc dù index login_time được thêm vào , do sử dụng hàm mysql tích hợp Date_ADD(), index này không có hiệu lực như thể hiện trong hình: Làm thế nào để tối ưu hóa tình huống này? Logic của các hàm tích hợp có thể được chuyển sang bên phải , như sau:

2.6 Thực hiện các thao tác với các cột index (chẳng hạn như +, -, , /), index sẽ không có hiệu lực

Cấu trúc bảng:

CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT,user_id varchar(32) NOT NULL,age int(11) DEFAULT NULL, PRIMARY KEY (id ), KEY idx_age (age) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Mặc dù trường age đã được đánh index, nhưng do cách viết dưới đây, index trực tiếp bị mất. . . Như trong hình: Do đó , không thể thao tác trên cột index, và nó có thể được xử lý trong code và sau đó được chuyển vào. ....

Bình luận

Bài viết tương tự

- vừa được xem lúc

Mô hình quan hệ - thực thể (Entity – Relationship Model)

Mô hình quan hệ thực thể (Entity Relationship model - E-R) được CHEN giới thiệu vào năm 1976 là một mô hình được sử dụng rộng rãi trong các bản thiết kế cơ sở dữ liệu ở mức khái niệm, được xây dựng dựa trên việc nhận thức thế giới thực thông qua tập các đối tượng được gọi là các thực thể và các mối

0 0 132

- vừa được xem lúc

[Embulk #1] Công cụ giúp giảm nỗi đau chuyển đổi dữ liệu

Embulk là gì. Embulk là một công cụ open source có chức năng cơ bản là load các record từ database này và import sang database khác.

0 0 55

- vừa được xem lúc

Window Functions trong MySQL, Nâng cao và cực kì hữu dụng (Phần II).

Chào mọi người, lại là mình đây, ở phần trước mình đã giới thiệu với mọi người về Window Functions Phần I. Nếu chưa rõ nó là gì thì mọi người nên đọc lại trước nha, để nắm được định nghĩa và các key words, tránh mắt chữ O mồm chứ A vì phần này mình chủ yếu sẽ thực hành với các Window Functions.

0 0 107

- vừa được xem lúc

Window Functions trong MySQL, Nâng cao và cực kì hữu dụng (Phần I).

Chào mọi người, mình mới tìm hiểu đc topic Window Functions cá nhân mình cảm thấy khá là hay và mình đánh giá nó là phần nâng cao. Vì ít người biết nên Window Functions thấy rất ít khi sử dụng, thay vì đó là những câu subquery dài dằng dặc như tin nhắn nhắn cho crush, và người khác đọc hiểu được câu

0 0 923

- vừa được xem lúc

Disable và Enable trigger trong Oracle

Origin post: https://www.tranthanhdeveloper.com/2020/12/disable-va-enable-trigger-trong-oracle.html.

0 0 41

- vừa được xem lúc

Lưu trữ dữ liệu với Data Store

. Data Store là một trong những componet của bộ thư viện Android JetPack, nó là một sự lựa chọn hoàn hảo để thay thế cho SharedPreferences để lưu trữ dữ liệu đơn giản dưới dạng key-value. Chúng ta cùng làm một so sánh nhỏ để thấy sự tối ưu của Data Store với SharedPreferences nhé.

0 0 71