banner
Apr 5, 2023
235 Views

Lại chuyện index mysql – leftmost prefix

Written by
banner

Note: nếu bạn muốn tìm hiểu về chủ đề mysql thì here you go https://blog.haonheo.com/?s=mysql

Tôi có 1 bảng như sau

Tôi đánh các index như sau:

Trong document của mysql nói rằng index trong mysql là leftmost prefix ví dụ đánh index (a,c,b) thì nó sẽ được dùng trong trường hợp bạn tìm kiếm (a), (a,c), (a,b,c) và sẽ không được dùng khi bạn tìm kiếm (a,b), (b), (c), (b,c)

Nhưng thật kỳ lạ khi bạn EXPLAIN câu lệnh tìm kiếm với điều kiện chứa (a,b) thì mysql vẫn nói rằng nó đang dùng index (a,c,b)

EXPLAIN
SELECT *
FROM test 
WHERE a=0 AND b=1;

=======RESULT 01======
id		:1
select_type	:SIMPLE
table		:test
type		:ref
posible_keys	:test_acb_IDX
key		:test_acb_IDX
key_len		:4
ref		:const
row		:60960
filtered	:10.0
Extra		:Using index condition

Bạn bắt đầu thấy thế giới thật giả dối, tới document mysql còn lừa bạn. Stop, thực ra không ai lừa ai ở đây cả. Hãy chú ý tới trường Extra đang thể hiện là Using index condition. Using index condition có nghĩa là nó đang dùng "ké" index vì đang tìm kiếm ab mà có sẵn 1 cái index đang có a ở đầu. Nếu a thỏa mãn điều kiện thì nó sẽ phải đọc cả row trong DB và tìm xem b trong đó có thỏa mãn điều kiện không. Using index condition sẽ có cost cao hơn Using index rất nhiều do Using index sẽ chỉ tìm trong index thôi.

Using index condition Pushdown

Bạn có thể thấy ngay khi tìm kiếm theo đúng index sẽ có các thông số đẹp hơn như bên dưới:

  • ref của RESULT 01 chỉ có 1 const trong khi nếu tìm kiếm theo đúng chuẩn là (a,c) như RESULT 02 sẽ là const, const như bên dưới
  • số row scan ở RESULT 01 tận 60960 trong khi nếu theo đúng như RESULT 02 chỉ có 1.
  • filteredRESULT 01 chỉ 10 còn ở RESULT 02 tận 100. 100 nghĩa là không phải scan row nào trong table cả (link).
EXPLAIN
SELECT *
FROM test
WHERE a=2 AND c=2;

=======RESULT 02======
id		:1
select_type	:SIMPLE
table		:test
type		:ref
posible_keys	:test_acb_IDX
key		:test_acb_IDX
key_len		:9
ref		:const,const
row		:1
filtered	:100
Extra		:NULL

Khi bạn tìm theo (b,c), lúc này không còn a ở đầu nữa nên sẽ không được dùng ké index (a,c,b) dẫn tới không còn index nào được sử dụng (RESULT 03)

EXPLAIN
SELECT *
FROM test
WHERE b=2 AND c=2;

=======RESULT 03======
id		:1
select_type	:SIMPLE
table		:test
type		:ALL
posible_keys	:NULL
key		:NULL
key_len		:NULL
ref		:NULL
row		:121,921
filtered	:1
Extra		:Using where

Bạn thấy đấy, đánh index là cả nghệ thuật đúng không nào ?

Article Tags:
· ·
Article Categories:
dev
banner

Leave a Reply

Your email address will not be published. Required fields are marked *