2009-04-16 23 views
8

Tôi đã thêm một chỉ mục toàn văn đến một trong các bảng cơ sở dữ liệu MySQL của tôi như sau:Tại sao cardinality của một chỉ mục trong MySQL vẫn không thay đổi khi tôi thêm một chỉ mục mới?

ALTER TABLE members ADD FULLTEXT(about,fname,lname,job_title); 

Vấn đề là sử dụng phpmyadmin tôi có thể thấy cardinality của chỉ số mới của tôi chỉ là. Điều này có nghĩa là chỉ mục sẽ không bao giờ được sử dụng?

Tôi đã chạy lệnh phân tích bảng nhưng dường như nó không làm gì cả.

analyze table members 

Các loại tương ứng của các trường index là varchar (100), varchar (100), văn bản, varchar (200) và động cơ sử dụng là MyISAM và bảng có khoảng 30.000 hàng, tất cả độc đáo. Phiên bản MySQL của tôi là 5.0.45.

Tôi có làm gì sai không?

Trả lời

13

Nếu bạn chỉ có 1 hàng trong bảng, thì cardinality cho chỉ mục phải là 1, tất nhiên. Nó chỉ đếm số lượng giá trị duy nhất.

Nếu bạn nghĩ chỉ mục là bảng tra cứu dựa trên nhóm (như băm), thì số lượng thẻ là số nhóm. Đây là cách nó hoạt động: Khi bạn xây dựng một chỉ mục trên một tập hợp các cột (a,b,c,d), thì cơ sở dữ liệu đi qua tất cả các hàng trong bảng, nhìn vào tứ giác theo thứ tự của 4 cột đó, cho mỗi hàng. Hãy nói rằng bảng của bạn trông như thế này:

a b c d e 
-- -- -- -- -- 
1 1 1 1 200 
1 1 1 1 300 
1 2 1 1 200 
1 3 1 1 200 

Vì vậy, những gì các cơ sở dữ liệu nhìn vào chỉ là 4 cột (a, b, c, d):

a b c d 
-- -- -- -- 
1 1 1 1 
1 2 1 1 
1 3 1 1 

Thấy rằng chỉ có 3 độc đáo hàng còn lại? Những người đó sẽ trở thành xô của chúng tôi, nhưng chúng tôi sẽ quay trở lại đó. Trong thực tế, cũng có một id hồ sơ, hoặc định danh hàng cho mỗi hàng trong bảng. Vì vậy, bảng ban đầu của chúng tôi trông như thế này:

(row id) a b c d e 
-------- -- -- -- -- -- 
00000001 1 1 1 1 200 
00000002 1 1 1 1 300 
00000003 1 2 1 1 200 
00000004 1 3 1 1 200 

Vì vậy, khi chúng ta nhìn vào chỉ có 4 cột (a, b, c, d), chúng tôi đang thực sự tìm kiếm cũng tại hàng id:

(row id) a b c d 
-------- -- -- -- -- 
00000001 1 1 1 1 
00000002 1 1 1 1 
00000003 1 2 1 1 
00000004 1 3 1 1 

Nhưng chúng tôi muốn làm tra cứu bằng cách (a, b, c, d) và không phải bởi id hàng, vì vậy chúng tôi sản xuất một cái gì đó như thế này:

(a,b,c,d) (row id) 
--------- -------- 
1,1,1,1 00000001 
1,1,1,1 00000002 
1,2,1,1 00000003 
1,3,1,1 00000004 

và cuối cùng, chúng tôi id nhóm tất cả các dãy hàng có giá trị nhận dạng (a, b, c, d) cùng nhau:

(a,b,c,d) (row id) 
--------- --------------------- 
1,1,1,1 00000001 and 00000002 
1,2,1,1 00000003 
1,3,1,1 00000004 

Thấy điều đó? Các giá trị của (a, b, c, d), là (1,1,1,1) (1,2,1,1) và (1,3,1,1) đã trở thành các khóa cho bảng tra cứu của chúng tôi vào các hàng của bảng gốc.

Thực ra, không có điều nào thực sự xảy ra, nhưng nó sẽ cung cấp cho bạn ý tưởng hay về cách thực hiện một chỉ mục "ngây thơ" (tức là tiến thẳng về phía trước) của chỉ mục.

Nhưng điểm mấu chốt là: cardinality chỉ đo số lượng hàng duy nhất có trong chỉ mục. Và trong ví dụ của chúng tôi đó là số lượng khóa trong bảng tra cứu của chúng tôi, là 3.

Hy vọng điều đó sẽ hữu ích!

+0

Cảm ơn thông tin chỉ mục. Rất tốt giải thích. Cardinality của chỉ số của tôi nên được nhiều hơn 1 cho rằng có 30000 hàng và hầu hết các thành viên có một tên khác nhau? – Tom

+0

Cảm ơn bạn đã giải thích về các chỉ mục, nó rất hay, nhưng lời giải thích của bạn không trả lời câu hỏi trên. –

+0

Bạn nói đúng, tôi đã không nói rõ kết luận cuối cùng: Tôi chỉ cho thấy rằng 4 hàng rơi vào 3 nhóm. Tôi chắc rằng bạn có thể phát minh ra một hàng khác có thể được thêm vào và sẽ rơi vào một trong 3 nhóm hiện tại của chỉ mục. Điều đó sẽ khiến số lượng xô không thay đổi, điều này cũng có nghĩa là số lượng của chỉ số không thay đổi. Xin lỗi vì điều đó. – scraimer

8

Tôi không thể trả lời chắc chắn lý do tại sao MySQL không tính toán cardinality, nhưng tôi có thể đoán. Các trạng thái MySQL manual:

Cardinality: Ước tính số lượng giá trị duy nhất trong chỉ mục. Điều này được cập nhật bằng cách chạy ANALYZE TABLE hoặc myisamchk -a. Cardinality được tính dựa trên số liệu thống kê được lưu trữ dưới dạng số nguyên, do đó giá trị không nhất thiết chính xác ngay cả đối với các bảng nhỏ. Thẻ càng cao thì cơ hội mà MySQL sử dụng chỉ mục càng nhiều khi tham gia càng lớn.

Chỉ mục FULLTEXT chỉ được sử dụng trong MATCH ... CHỌN (...) truy vấn, buộc chỉ mục được sử dụng. Cú pháp MATCH ... AGAINST không hoạt động nếu không có chỉ mục FULLTEXT trên các trường đó.

Đoán của tôi là thẻ không được tính vì nó thực sự không cần thiết.

Lưu ý rằng các tìm kiếm chống lại chỉ mục hoạt động mặc dù cardinality chưa được đặt.

Đối với bản ghi, câu lệnh ANALYZE TABLE foobar dường như thiết lập chính xác cardinality.