Làm thế nào tôi nên tối ưu hóa lưu trữ cho bảng này?


7

Tôi đang sử dụng MySql để lưu trữ một bảng cơ bản có định dạng này:

    id      int(11)          //Auto-Incrementing ID
    data    varchar(5120)    //Random input data, compressed by a program, not mysql.
    -----------------------
    Row size ø  916 B

Điều đó thật rắc rối, bởi vì hiện tại tôi có khoảng 5.000 hồ sơ mỗi tháng và tôi muốn tối ưu hóa điều đó tốt hơn là kết thúc trung bình ở mức 1mb / 1000 hồ sơ.

Tôi thiết lập nó theo cách này ban đầu bởi vì tôi muốn có thể chụp các bộ lớn hơn, nhưng chúng rất không thường xuyên, như bạn có thể thấy ở đây bằng biểu đồ này:

nhập mô tả hình ảnh ở đây

Liên kết với API đồ thị

count   n*128 bytes
+-------+----------
1       28
1       26
1       24
2       22
8       21
4       20
13      19
12      18
16      17
27      16
43      15
58      14
69      13
114     12
184     11
262     10
399     9
588     8
807     7
1224    6
1245    5
546     4
73      3
9       2
6       1
1       0

Mối quan tâm chính của tôi ở đây là tôi đã lãng phí bao nhiêu không gian chỉ để chứa phần đuôi của biểu đồ đó, và điều gì xảy ra khi tôi kết thúc với các ngoại lệ thậm chí còn lớn hơn? Tôi sẽ phải tăng kích thước hàng của mình một lần nữa, khi khoảng 80% dữ liệu vừa khít với khối varar 1024, 1/5 kích thước của những gì tôi đang sử dụng.

Vì vậy, làm thế nào tôi nên xây dựng điều này ở nơi đầu tiên?

Câu trả lời:


4

Vì nó đã được xây dựng rồi, hãy nhìn vào những gì bạn có. Có một cách thú vị để lập kế hoạch định nghĩa cột cho dữ liệu hiện tại. Nếu tên bảng là mydata, hãy thử chạy truy vấn này:

CHỌN dữ liệu TỪ mydata PROCEDURE ANALYZE ();

Điều này sẽ không hiển thị bất kỳ dữ liệu của bạn. Điều này sẽ tự kiểm tra cột data, tính toán thống kê dựa trên 256 giá trị riêng biệt đầu tiên (theo mặc định, bạn có thể chỉ định số lượng giá trị riêng biệt) và đề xuất loại cột thích hợp mà bảng nên có.

Miễn là bảng là MyISAM, đừng quá lo lắng về kích thước hàng vì định dạng hàng mặc định là NĂNG ĐỘNG. Nếu bảng là InnoDB (và tôi chắc chắn hy vọng là không), vui lòng đảm bảo dữ liệu không phải là một phần của KHÓA CHÍNH. Chỉ số được nhóm của bạn sẽ phát triển như đổ MiracleGro không pha loãng vào sân sau của bạn.

Bạn có thể cần chia cột dữ liệu thành các khối 128 và chạy MD5 (đầu ra 32 ký tự) hoặc SHA1 (đầu ra 40 ký tự) và nối các đầu ra MD5 hoặc SHA1 đó và lưu trữ chúng. Điều đó sẽ tiết kiệm ở 75% lưu trữ. Hãy vui vẻ cố gắng để mã mà chia tay. Đây chỉ là một lời đề nghị lan man ra khỏi đỉnh đầu của tôi.

Bạn có thể muốn xem xét sử dụng Sphinx Indexing là tốt.


2

Đối với MyISAM, nếu bạn không bao giờ CẬP NHẬT hoặc XÓA các bản ghi, một bản ghi có N byte cho blob sẽ lấy N + 8 byte trong tệp .MYD.

MyISAM PK sẽ được tìm thấy trong tệp .MYI; nó sẽ khá nhỏ - khoảng 11 byte / hàng, cộng với một ít chi phí, được làm tròn lên đến các khối 1KB.

Nếu bạn đang sử dụng InnoDB, bố cục khá phức tạp. Có các khối dữ liệu 16KB không bao giờ đầy đủ, có các phạm vi blob (ngay cả đối với VARCHAR), sẽ khởi động sau 767 byte (có thể sớm hơn, tùy thuộc vào phiên bản), v.v. Các phạm vi được phân bổ trong các đoạn 1MB. Lập kế hoạch trên một cái gì đó như trung bình 2N byte mỗi hàng.

InnoDB PK được lưu trữ cùng với dữ liệu, vì vậy nó hoàn toàn được bao gồm ở trên. Và, là AUTO_INCREMENT, các khối của bạn sẽ có xu hướng tương đối đầy đủ. Lưu ý: các khối có kích thước 16KB, cho phép bạn ít nhất 20 mỗi khối.

Đừng chơi trò chơi với chunk của riêng bạn; nó sẽ làm chậm mọi thứ, làm phức tạp mã của bạn, v.v. Đĩa rất rẻ. (Vâng, thật vui khi chơi những trò chơi như vậy.)

Có vẻ như một nửa hồ sơ của bạn sẽ không vượt qua ngưỡng 767.

Một bên: Nếu blob là dữ liệu nén, bạn thực sự nên sử dụng BLOB, không phải VARCHAR. VARCHAR giả định các thuộc tính CHARACTER SET, sẽ thực sự đốt cháy bạn nếu bạn chuyển sang utf8. Nếu bạn phải sử dụng VAR-xx, hãy sử dụng VARBINARY.

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.