Mysql: tạo chỉ mục trên 1,4 tỷ hồ sơ


9

Tôi có một bảng với 1,4 tỷ hồ sơ. Cấu trúc bảng như sau:

CREATE TABLE text_page (
    text VARCHAR(255),
    page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii

Yêu cầu là tạo một chỉ mục trên cột text.

Kích thước bàn khoảng 34G.

Tôi đã cố gắng tạo chỉ mục bằng tuyên bố sau:

ALTER TABLE text_page ADD KEY ix_text (text)

Sau 10 giờ chờ đợi, cuối cùng tôi đã từ bỏ phương pháp này.

Có bất kỳ giải pháp khả thi về vấn đề này?

CẬP NHẬT : bảng không có khả năng được cập nhật hoặc chèn hoặc xóa. Lý do tại sao để tạo chỉ mục trên cột textlà vì loại truy vấn sql này sẽ được thực thi thường xuyên:

SELECT page_id FROM text_page WHERE text = ?

CẬP NHẬT : Tôi đã giải quyết vấn đề bằng cách phân vùng bảng.

Bảng được phân chia thành 40 mảnh trên cột text. Sau đó, việc tạo chỉ mục trên bảng mất khoảng 1 giờ để hoàn thành.

Có vẻ như việc tạo chỉ mục MySQL trở nên rất chậm khi kích thước bảng trở nên rất lớn. Và phân vùng làm giảm bảng thành thân nhỏ hơn.


1
Có gì sai khi sử dụng CREATE INDEXcâu lệnh bình thường ?

Tôi muốn đề xuất câu hỏi này có thể tốt hơn trên ServerFault - nó giống với quản trị viên DB hơn là câu hỏi lập trình.
từ đó

@Derk: cách tiếp cận CREATE INDEX bình thường quá chậm. Tôi phải hoàn thành nhiệm vụ trong vòng 1 ngày.

1
Hmm ... tôi không nghĩ rằng bạn có thể vượt qua điều này. Xây dựng chỉ mục yêu cầu DBMS quét qua tất cả các bản ghi, thu thập các trường "văn bản" của chúng và chèn / thay đổi các nút / cây con tương ứng. Và điều này mất nhiều thời gian cho 34G ...
chiccodoro

Máy chủ DB của bạn có bao nhiêu bộ nhớ? Bạn đã cấu hình MySQL để sử dụng tất cả bộ nhớ đó, hay nó tự giới hạn?

Câu trả lời:


4

Nó có thể là hệ thống của bạn không theo nhiệm vụ? Tôi không sử dụng MySQL (SQL Server tại đây), nhưng tôi biết nỗi đau của việc lập chỉ mục một bảng nhập 800 triệu. Về cơ bản .... bạn cần phần cứng phù hợp cho việc đó (như trong: rất nhiều đĩa nhanh). Bây giờ tôi sử dụng gần một chục Velociraptors và hiệu suất rất tuyệt;)

Máy chủ SQL (không phải là MS SQL Server, nhưng là máy chủ cơ sở dữ liệu sử dụng SQL) sống và chết với quyền truy cập đĩa và các đĩa thông thường không phụ thuộc vào nhiệm vụ của các hoạt động lớn hơn.


Tôi nghi ngờ rằng việc tạo chỉ mục thường rất nhanh nếu số lượng hồ sơ nhỏ; nói, hàng triệu. Nhưng khi số lượng lên tới hàng tỷ, việc tạo chỉ mục trở nên quá chậm. Có vẻ như sự tăng trưởng thời gian là theo cấp số nhân.

Không nên thực sự. MySQL nói chung có giới hạn, nhưng nó không phải là một cơ sở dữ liệu tào lao, và điều đó sẽ RẤT tệ. Việc tạo chỉ mục trở nên chậm hơn, nhưng bằng log (n), chứ không phải (n), vì vậy nó không thực sự xấu.
TomTom

4

Bạn có thể muốn tạo một chỉ mục trên các ký tự đầu tiên (ví dụ: 10) của trường văn bản.

Từ Tài liệu:

Chỉ mục có thể được tạo chỉ sử dụng phần đầu của các giá trị cột, sử dụng cú pháp col_name (length) để chỉ định độ dài tiền tố chỉ mục:

CREATE INDEX ix_text ON text_page (text(10))

4

Tôi đã giải quyết vấn đề bằng cách phân vùng bảng.

Bảng được phân chia thành 40 mảnh trên cột text. Sau đó, việc tạo chỉ mục trên bảng mất khoảng 1 giờ để hoàn thành.

Có vẻ như việc tạo chỉ mục MySQL trở nên rất chậm khi kích thước bảng trở nên rất lớn. Và phân vùng làm giảm bảng thành thân nhỏ hơn.


Vậy 40 x 1 giờ là dưới 10 giờ?
symcbean

3

Đặt sort_buffer_size thành 4GB (hoặc nhiều hơn bạn có thể tùy thuộc vào dung lượng bộ nhớ của bạn).

Ngay bây giờ, chỉ mục tạo đang thực hiện sắp xếp nhưng vì bạn có sort_buffer_size 32 MB, về cơ bản, nó không cần thiết phải phá hủy ổ cứng.


Những bài viết được không đồng ý khá nhiều trực tiếp với bạn: xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size và tốt hơn ronaldbradford.com/blog/... Nghe có vẻ như đó không phải là một giá trị toàn cầu, đó là mỗi truy vấn, vì vậy đó là 4GB cho mỗi truy vấn mà bạn đề xuất. Ngoài ra, khi vượt quá 256K, nó được ánh xạ mem vào đĩa thay vì là bộ nhớ trong thực tế. Nếu bạn giữ nó nhỏ, nó đòi hỏi nhiều lượt, nhưng nó sẽ tránh được đĩa (nó không trao đổi).
Ry4an Brase

3

Nếu bạn không cần thực hiện các truy vấn như:

SELECT page_id FROM text_page WHERE text LIKE '?%';

Tôi sẽ đề nghị tạo một cột băm mới và lập chỉ mục bảng theo cột. Kích thước quá mức của bảng + chỉ mục có thể nhỏ hơn nhiều.

CẬP NHẬT : Nhân tiện, 1,4 tỷ số nguyên khóa chính chiếm khoảng 6 GB, đó là độ dài trung bình của chuỗi dưới 30 ký tự, đó là lập chỉ mục trên tiền tố có thể thích hợp hơn.

Bạn cũng nên xem qua công cụ lưu trữ MERGE .


2

Một cách để làm điều này là tạo một bảng mới với bộ chỉ mục và sao chép dữ liệu vào bảng mới.

Ngoài ra, hãy chắc chắn rằng bạn có đủ không gian tạm thời.


1
Tôi đã thử phương pháp này. Sau 10 giờ, ít hơn 1% dữ liệu đã được sao chép sang bảng mới.

1
Anh bạn ... đó là hồ sơ 1,4 BILLION. Không phải triệu, HÓA ĐƠN. Đó là rất nhiều. Nó sẽ mất một lúc bất kể.

Nếu bạn chọn làm phương pháp này, hãy chia bản sao thành các phần nhỏ hơn. Nói khoảng 100 đến 200 triệu cho mỗi bản sao.

1
@ dịch ngược, chia nó thành các phần nhỏ hơn sẽ không làm gì cả (thực ra, nó có thể làm cho nó kém hiệu quả hơn). @Bryan, ngay cả với 1,4 tỷ hồ sơ, không nên mất 1.000 giờ.

0

Trong trường hợp bạn vẫn đang tự hỏi làm thế nào để làm điều này tốt nhất, tôi sẽ đề nghị bạn sử dụng một công cụ thay đổi bảng trực tuyến.

Có rất nhiều trong số họ trên internet, một trong những người nổi tiếng là:

Chúng tôi có cùng các vấn đề với các bảng lớn (hơn 500 triệu bản ghi) và việc thay đổi diễn ra hoàn hảo. Nó tạo một bảng tmp mới, thêm kích hoạt trên bảng gốc (đối với bản ghi cập nhật / xóa / chèn mới) và trong thời gian đó, nó sao chép tất cả các bản ghi vào bảng mới (với cấu trúc mới)

Chúc may mắn!

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.