MySQL index optimize B-Tree

2316

Có rất nhiều cách khác nhau để tối ưu hoá câu lệnh SQL nâng cao performance. Một trong số đó là đánh index cho các fields của table.

I.Index là gì

index là việc cấu trúc dữ liệu, lưu trữ theo một cơ chế nào đó để tìm ra các record một cách nhanh chóng.

Index là rất cần thiết để tăng performace và ngày càng trở nên quan trọng hơn nếu dữ liệu trong database của bạn ngày một lớn, đối với các hệ thống nhỏ thì việc đánh index hầu như không có ý nghĩa, nhưng một khi data trong db ngày một tăng, thì các truy vấn db có thể trở nên chậm chập tỷ lệ với độ tăng data trong db.

Việc hiểu sai về index có thể dẫn tới nguyên nhân làm cho performance không những không được cải thiện mà còn trở nên ì ạch hơn.

cách đơn giản nhất để hiểu về cơ chế index làm việc trong MySQL đó là nghĩ về việc đánh số trang trong một quyển sách. Để tìm một topic cụ thể trong cuốn sách bạn thường tìm đến phần mục lục và tìm trang số thứ bao nhiêu trong quyển sách theo như topic mà bạn muốn. Trong MySQL có một cơ chế lưu trữ index theo cách tương tự.

Giả sử khi chạy câu lệnh MySQL sau:

Index sẽ được đánh trên cột actor_id, MySQL sẽ sử dụng index để tìm ra những dòng mà actor_id của nó là 5. Hay nói cách khác nó sẽ thực thi việc tìm kiếm dữ liệu trên value index và trả về bất cứ dòng dữ liệu nào có chứa dữ liệu đầu vào. Một Index có chứa dữ liệu từ một hoặc nhiều cột khác nhau trong table. Nếu bạn đánh index cho nhiều cột thì thứ tự cột là rất quan trong bởi vì MySQL chỉ có thể tìm kiếm hiệu quả về phía bên trái prefix của index (sẽ nói rõ hơn qua các ví dụ bên dưới). Việc tạo index trên 2 cột không giống với việc tạo index trên 2 cột riêng rẽ.

** Các kiểu index**

Mỗi một kiểu được thiết kế cho các mục đích khác nhau, Index được thực thì ở tầng lưu trữ dữ liệu, do đó nó không có một chuẩn nào cả.

Có rất nhiều kiểu index mà điển hình là B-tree index, hash index, R-tree index, full-text index …

II. B-Tree index

Thông thường khi ta nói đến index mà không chỉ rõ loại index thì đó là ám chỉ đến B-Tree index, nó sử dụng B-Tree data structure để lưu trữ dữ liệu. Hầu hết các bộ máy lưu trữ dữ liệu của MySQL đều hỗ trợ B-TRee index.

Ý tưởng chính của B-Tree đó là tất cả các giá trị được lưu theo một trật tự. và mỗi node lá sẽ có chung khoảng cách với gốc.

Một B-Tree index có thể làm nhanh tốc độ truy vấn là vì bộ máy lưu trữ dữ liệu sẽ không scan dữ liệu trên toàn bộ bảng để tìm dữ liệu cần có. Thay vào đó nó sẽ bắt đầu từ node gốc, mỗi một điểm trên nốt gốc sẽ giữ những con trỏ trỏ tới những nốt con và bộ máy lưu trữ sẽ dựa vào những con trỏ để scan dữ liệu. Nó sẽ tìm con trỏ bên phải bằng cách nhìn vào dữ liệu ở node pages, các node page có chứa dữ liệu của các node con. Bộ máy lưu trữ sẽ xác định việc dữ liệu có tồn tại hay không hay tìm được dữ liệu ở leaf page.

B-Tree lưu trữ indexed columns theo một thứ tự vì vậy chúng rất hữu ích cho việc tìm kiếm một khoảng dữ liệu. Ví dụ index được đánh cho một trường dữ liệu kiểu text, nếu tìm kiếm theo tên bắt đầu bằng một chữ cái nào đó thì việc tìm kiếm sẽ rất hiệu quả

Giả sử có table

index sẽ chứa giá trị của last_name, first_name, và dob cho mỗi dòng dữ liệu,

Chú ý: Index sắp xếp dữ liệu thông qua thứ tự cột index trong câu lệnh tạo table

II.1. Các kiểu queries có thể sử dụng B-Tree index:

B-Tree index sẽ hiệu quả với việc tìm kiếm với full key value, key range hoặc key prefix. B-Tree chỉ thực sự hữu dụng khi search từ phía trái của index có nghĩa là: trong ví dụ trên index là

thì

nhưng câu dưới đây index sẽ không được dùng

cho dù đổi trật trự trong điều kiện where cũng không có tác dụng vì trong điều kiện where không có last_name

Match the full value

Match tất cả key, value của dữ liệu cho tất cả các cột trong index

Match a leftmost prefix

  • Index chỉ được áp dụng khi truy vấn với column đầu tiên last_name

Match a column prefix

  • Có thể match phần đầu của value, nó chỉ được áp dụng cho cột đầu tiên của index ví dụ tìm last_name bắt đầu bằng chữ “K” chẳng hạn

Match với một khoảng dữ liệu

  • Cho phép match data với một khoảng value truyền vào, và nó chỉ áp dụng cho column đầu tiên của index

Match chính xác một phần và kết hợp match trường khác trong một khoảng dữ liệu

  • Index này cho phép bạn tìm ra chính xác last_name sau đó tìm first name với môt khoảng giá trị như first_name bắt đầu bằng “k” chẳng hạn.

Index chỉ cho các câu truy vấn lấy dữ liệu

Một lưu ý là B-Tree chỉ áp dụng cho việc truy vấn lấy ra dữ liệu chứ không có tác dụng cải thiện việc lưu trữ dữ liệu xuống db.

Cơ hội gặp gỡ, học hỏi kinh nghiệm với các chuyên gia Xamarin trong & ngoài nước!

Hạn Chế của B-Tree:

  • Nó sẽ là không hữu ích nếu việc tìm kiếm trong câu lệnh điều kiện không bắt đầu từ phía trái của index keys, như ở ví dụ trên

Nếu ta tìm kiếm theo first_name, dob => không có last_name, không bắt đầu từ phía trái của key nên index sẽ không có tác dụng trong trường hợp này.

Một điều nữa đó là index sẽ không có tác dụng search một trường được kết thúc bởi một ký tự nào đó

ví dụ:

possible_keys là null.

  • Hạn chế tiếp theo là bạn không thể bỏ qua cột của index, nghĩa là khi truy vấn nếu bạn không bắt đầu hay các field tìm kiếm không có trong thứ tự của keys thì index sẽ không có tác dụng cho toàn bộ các column ở trong condition
  • Ví dụ tôi sẽ bỏ cột giữa first_name khi truy vấn key(last_name, first_name, dob)

thì chỉ có cột đầu tiên last_name là được dùng index

Một giới hạn nữa đó là khi trong điều kiện where của câu truy vấn nếu bất kỳ một columns nào đó sử dụng range condition thì những column đứng sau nó sẽ không được index

ví dụ

select * from People where last_name=’Peter’ and first_name like ‘%r’ and dob=’1990

tìm kiếm last name kết thúc bởi chữ r, đây là range condition. Như vậy khi tìm kiếm dob sẽ không được sử dụng index, mà index chỉ có tác dụng với 2 trường last_name và fist_name

Kết

Đánh index cho bảng dữ liệu là khá quan trọng, nó giúp làm tăng hiệu năng truy vấn xuống db của hệ thống,

bên cạnh đó nếu hiểu sai, áp dụng sai thì việc đánh Index trở nên vô nghĩa không có tác dụng tăng performance mà còn làm chậm

Techtalk via Viblo

CHIA SẺ