Có bất kỳ sự tăng hiệu suất nào trong việc lập chỉ mục một trường boolean không?


102

Tôi sắp viết một truy vấn bao gồm một WHERE isok=1. Như tên của nó, isoklà một trường boolean (thực sự là một trường TINYINT(1) UNSIGNEDđược đặt thành 0 hoặc 1 nếu cần).

Có bất kỳ hiệu suất tăng trong việc lập chỉ mục trường này không? Công cụ (trong trường hợp này là InnoDB) hoạt động tốt hơn hay tệ hơn khi tra cứu chỉ mục?


có thể trùng lặp của Indexing lĩnh vực boolean
Maxim Krizhanovsky

Câu trả lời:


79

Không hẳn vậy. Bạn nên nghĩ về nó như một cuốn sách. Nếu chỉ có 3 loại từ trong một cuốn sách và bạn lập chỉ mục tất cả chúng, bạn sẽ có cùng số trang mục lục như các trang bình thường.

Sẽ có hiệu suất tăng nếu có tương đối ít bản ghi của một giá trị. Ví dụ: nếu bạn có 1000 bản ghi và 10 bản ghi trong số đó là ĐÚNG, thì sẽ hữu ích nếu bạn tìm kiếm vớiisok = 1

Như Michael Durrant đã đề cập, nó cũng làm cho việc viết chậm hơn.

CHỈNH SỬA: Có thể trùng lặp: Lập chỉ mục các trường boolean

Ở đây nó giải thích rằng ngay cả khi bạn có một chỉ mục, nếu bạn có quá nhiều bản ghi, nó sẽ không sử dụng chỉ mục nào. MySQL không sử dụng chỉ mục khi kiểm tra = 1, nhưng sử dụng nó với = 0


4
Có vẻ như nó "yes: 2 - no: 1". Ai đó sai ở đây, nhưng ai?
Niet the Dark Absol

4
Điều này không hoàn toàn chính xác, không có chỉ mục mySql cần phải quét toàn bộ bảng để tìm các hàng có liên quan.
ilanco

4
nếu không nó sẽ quét toàn bộ chỉ mục. (dài như vậy trong hầu hết các trường hợp)
Michael Koper

1
Nó có thể tạo ra sự khác biệt. Chỉ cần cắt giảm một nửa thời gian thực hiện truy vấn chỉ bằng cách thêm một chỉ mục, và các lần viết rất hiếm và rẻ đến mức chúng tôi không thực sự quan tâm đến hình phạt. Như với tất cả mọi thứ, đừng cho rằng, biện pháp (còn vì cơ sở dữ liệu không phải lúc nào thực sự cư xử như bạn muốn một cách logic mong đợi họ)
Eelco

6
Điều này giả định phân phối bằng nhau giữa TRUE và FALSE. Như đã đề cập bởi @oucil bên dưới, nếu bạn đang tìm kiếm một giá trị boolean khá hiếm, thì vẫn có thể mất một lúc. Không nói rằng bạn nên lập chỉ mục luôn luôn, nhưng tôi sẽ cho rằng bản chất dữ liệu của bạn và các truy vấn của bạn cũng quan trọng trong hầu hết các công cụ cơ sở dữ liệu.
mahemoff

117

Chỉ cần nói rõ hơn về một số câu trả lời khác ở đây, vì theo kinh nghiệm của tôi, những người đang xem những câu hỏi như thế này đều ở trong cùng một con thuyền với chúng tôi, chúng tôi đều nghe nói rằng lập chỉ mục các trường Boolean là vô nghĩa, nhưng ...

Chúng tôi có một bảng với khoảng 4 triệu hàng, chỉ khoảng 1000 hàng tại một thời điểm sẽ có một công tắc Boolean được gắn cờ và đó là những gì chúng tôi tìm kiếm chống lại. Việc thêm một chỉ mục vào trường Boolean của chúng tôi đã tăng tốc các truy vấn theo thứ tự độ lớn, nó đi từ khoảng hơn 9 giây đến một phần của giây.


Có, mặc dù bạn nên cố gắng hiểu rõ 'lý do tại sao' của mọi thứ, hãy luôn đo lường cùng với và thử những thứ khác nhau trên tập dữ liệu thực tế của bạn để xem liệu lý thuyết của bạn có khớp với hành vi thực tế của công cụ db hay không (bạn sẽ ngạc nhiên ... )
Eelco

8
@Eelco Bạn nói đúng, nhưng trong trường hợp này, kết quả thực sự khớp với lý thuyết cơ bản. Ý tưởng cơ bản rằng nó sẽ không đáng kể chỉ có ý nghĩa nếu bạn có khoảng 50% khả năng tìm thấy các mục phù hợp với tìm kiếm của mình. Sau đó, để tìm 100 mục phù hợp, DB cần lặp lại 200 mục. Nhưng nếu các mục chỉ khớp với 1% thời gian, nó sẽ cần lặp lại 10.000 mục.
mahemoff

7
Tôi thích khi mọi người thực sự thử mọi thứ trên sân và đưa ra phản hồi về hiệu suất thay vì chỉ triết lý.
Viktor Joras

WHERE my_col > 0 thay vì my_col = 1dường như cũng giúp tăng tốc độ
Aaron

27

Nó phụ thuộc vào các truy vấn thực tế và tính chọn lọc của tổ hợp chỉ mục / truy vấn.

Trường hợp A : điều kiện WHERE isok = 1và không có gì khác ở đó:

SELECT *
FROM tableX
WHERE isok = 1
  • Nếu chỉ mục đủ chọn lọc (giả sử bạn có 1M hàng và chỉ có 1k isok = 1), thì công cụ SQL có thể sẽ sử dụng chỉ mục và nhanh hơn so với khi không có nó.

  • Nếu chỉ mục không đủ chọn lọc (giả sử bạn có 1 triệu hàng và hơn 100 nghìn hàng có isok = 1), thì công cụ SQL có thể sẽ không sử dụng chỉ mục và thực hiện quét bảng.

Trường hợp B : điều kiện WHERE isok = 1và nhiều thứ khác:

SELECT *
FROM tableX
WHERE isok = 1
  AND another_column = 17

Sau đó, nó phụ thuộc vào những chỉ số khác mà bạn có. Chỉ mục trên another_columncó thể sẽ được chọn lọc hơn chỉ mục chỉ isokcó hai giá trị khả dĩ. Một chỉ mục trên (another_column, isok)hoặc (isok, another_column)thậm chí sẽ tốt hơn.


Tôi nghĩ, đây là câu trả lời đúng hơn so với câu trên cùng. cũng là sự phân phối của dữ liệu.
tyan

12

Nó phụ thuộc vào sự phân bố của dữ liệu.

Hãy tưởng tượng tôi có một cuốn sách với 1000 trang được đánh máy chặt chẽ và các từ duy nhất trong cuốn sách của tôi là 'có' và 'không' được lặp đi lặp lại và được phân phối ngẫu nhiên. Nếu tôi được yêu cầu khoanh tròn tất cả các trường hợp 'có', một chỉ mục ở phía sau cuốn sách có giúp ích gì không? Nó phụ thuộc.

Nếu có phân phối ngẫu nhiên một nửa của có và không, thì việc tra cứu trong chỉ mục sẽ không hữu ích. Chỉ mục sẽ làm cho cuốn sách lớn hơn rất nhiều, và dù sao thì tôi sẽ nhanh hơn chỉ bắt đầu từ phía trước và làm theo cách của tôi qua từng trang để tìm kiếm tất cả các trường hợp 'có' và khoanh tròn chúng, thay vì tìm kiếm từng mục trong chỉ mục và sau đó lấy tham chiếu từ mục nhập chỉ mục đến trang mà nó tham chiếu.

Nhưng nếu có, chẳng hạn, chỉ có mười trường hợp 'có' trong cuốn sách nghìn trang của tôi và mọi thứ khác chỉ là hàng triệu không, thì một chỉ mục sẽ giúp tôi tiết kiệm rất nhiều thời gian trong việc tìm kiếm mười trường hợp 'có' đó và khoanh tròn chúng. .

Trong cơ sở dữ liệu cũng vậy. Nếu đó là phân phối 50:50, thì một chỉ mục sẽ không giúp ích được gì - công cụ cơ sở dữ liệu tốt hơn là chỉ cần xem xét dữ liệu từ đầu đến cuối (quét toàn bộ bảng) và chỉ mục sẽ chỉ làm cho cơ sở dữ liệu lớn hơn và chậm hơn để viết và cập nhật. Nhưng nếu nó giống như phân phối 4000: 1 (theo oucil trong chủ đề này), thì một tìm kiếm chỉ mục có thể tăng tốc độ nó lên rất nhiều, nếu nó là 1 trong 4000 mục mà bạn đang tìm kiếm.


5

Không, thường là không.

Bạn thường lập chỉ mục các trường để tìm kiếm khi chúng có tính chọn lọc / số lượng cao. Cardinality của một trường boolean rất thấp trong hầu hết các bảng. Nó cũng sẽ làm cho các bài viết của bạn chậm hơn một chút.


3

Trên thực tế, điều này phụ thuộc vào các truy vấn bạn chạy. Nhưng, nói chung là có, cũng như lập chỉ mục một trường thuộc bất kỳ loại nào khác.


2

Có một chỉ mục sẽ cải thiện hiệu suất, hãy kiểm tra đầu ra của EXPLAIN có và không có chỉ mục.

Từ các tài liệu:

Chỉ mục được sử dụng để tìm các hàng có giá trị cột cụ thể một cách nhanh chóng. Nếu không có chỉ mục, MySQL phải bắt đầu với hàng đầu tiên và sau đó đọc qua toàn bộ bảng để tìm các hàng có liên quan. Bàn càng lớn, chi phí này càng nhiều. Nếu bảng có chỉ mục cho các cột được đề cập, MySQL có thể nhanh chóng xác định vị trí cần tìm ở giữa tệp dữ liệu mà không cần phải xem tất cả dữ liệu.

Tôi nghĩ rằng cũng có thể an toàn khi nói rằng một chỉ mục sẽ KHÔNG GIẢM hiệu suất trong trường hợp này, vì vậy bạn chỉ có thể đạt được từ nó.


2
Một chỉ mục cung cấp rất nhiều dữ liệu trên đĩa cứng và nó làm cho việc ghi chậm hơn, do đó bạn không chỉ thu được từ nó.
Michael Koper

1
Đúng, nhưng trong trường hợp này, một TINYINT(1) UNSIGNEDcột, kích thước của dữ liệu sẽ nhỏ.
ilanco

Và chi phí viết thêm có lẽ khá thấp
Eelco

Không phải kích thước của chỉ mục sẽ tăng lên theo số hàng mà nó trỏ đến, chứ không chỉ là kích thước của trường được lập chỉ mục?
poolie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.