Lý do ** KHÔNG ** để sử dụng công cụ lưu trữ MEMOR trong MySQL là gì?


28

Gần đây tôi phát hiện ra rằng MySQL có một công cụ "bộ nhớ" mà tôi không biết (hầu hết các công việc cơ sở dữ liệu của tôi là dành cho các dự án sở thích để tôi tìm hiểu những gì tôi cần khi tôi đi). Có vẻ như tùy chọn này sẽ mang lại cho tôi hiệu suất được cải thiện đáng kể, vì vậy tôi tự hỏi liệu có bất kỳ nhược điểm nào đi kèm với nó không. Hai cái mà tôi biết là:

  1. Tôi cần có đủ RAM để giữ (các) bảng trong câu hỏi.
  2. Các bảng bị mất nếu máy tắt.

Tôi tin rằng # 1 không phải là vấn đề vì tôi đang sử dụng AWS EC2 và có thể chuyển sang loại phiên bản có nhiều bộ nhớ hơn nếu cần. Tôi tin rằng tôi có thể giảm thiểu số 2 bằng cách trả lại đĩa khi cần.

Có vấn đề gì khác không? Công cụ bộ nhớ có thể cho hiệu năng kém hơn MyISAM hoặc InnoDB không? Tôi nghĩ rằng tôi đã đọc một cái gì đó mà các chỉ số khác nhau với công cụ này; đây có phải là điều tôi cần lo lắng không?

Câu trả lời:


27

Nhìn vào danh sách tính năng sẵn có tại http://dev.mysql.com/doc/refman/5.1/en/memory-st Storage-engine.html hai vấn đề có thể xảy ra:

  1. Không có giao dịch hoặc hỗ trợ FK, có nghĩa là bạn sẽ phải quản lý tính toàn vẹn giao dịch và tính toàn vẹn tham chiếu trong mã của riêng bạn (điều này có thể kém hiệu quả hơn nhiều so với việc để DB làm điều này cho bạn, mặc dù điều đó phụ thuộc rất nhiều vào ứng dụng của bạn mô hình hành vi dự kiến).
  2. Chỉ khóa mức bảng: đây có thể là một rào cản đáng kể đối với khả năng mở rộng nếu ứng dụng của bạn cần nhiều trình ghi đồng thời vào cùng một tập hợp bảng hoặc trong trường hợp các thao tác đọc của bạn sử dụng khóa để đảm bảo đọc dữ liệu nhất quán - trong trường hợp đó là bảng dựa trên đĩa hỗ trợ độ chi tiết khóa tốt hơn nhiều sẽ hoạt động tốt hơn nhiều nếu đủ nội dung của nó hiện được lưu trong bộ nhớ cache.

Ngoài ra, giả sử bạn có đủ RAM, bảng dựa trên bộ nhớ phải nhanh hơn bảng dựa trên đĩa. Rõ ràng bạn cần phải có yếu tố chụp ảnh nhanh vào đĩa để giải quyết vấn đề xảy ra khi thiết lập máy chủ được đặt lại, điều này có khả năng phủ nhận hoàn toàn lợi ích hiệu suất tổng thể nếu dữ liệu cần được ghi lại thường xuyên (nếu bạn có thể sống với việc mất một ngày dữ liệu trong trường hợp như vậy bạn chỉ có thể sao lưu một lần mỗi ngày, nhưng trong hầu hết các trường hợp sẽ không được chấp nhận).

Một sự thay thế có thể là:

  1. Sử dụng các bảng dựa trên đĩa, nhưng đảm bảo rằng bạn có quá nhiều RAM để giữ tất cả RAM trong bất kỳ thời điểm nào (và "đủ RAM" có thể nhiều hơn bạn nghĩ khi bạn cần tính đến bất kỳ quy trình nào khác trên máy, HĐH Bộ đệm IO / bộ đệm và vv
  2. Quét toàn bộ nội dung (tất cả các trang dữ liệu và chỉ mục) của bảng trên mỗi lần khởi động để tải trước nội dung vào bộ nhớ với SELECT * FROM <table> ORDER BY <pkey fields>mỗi bảng theo sau SELECT <indexed fields> FROM <table> ORDER BY <index fields>cho mỗi chỉ mục

Bằng cách này, tất cả dữ liệu của bạn nằm trong RAM, bạn chỉ phải lo lắng về hiệu năng I / O cho các hoạt động ghi. Nếu bộ công việc chung của ứng dụng của bạn nhỏ hơn nhiều so với toàn bộ DB (thường là như vậy - trong hầu hết các ứng dụng, hầu hết người dùng sẽ chỉ nhìn vào dữ liệu gần đây nhất nếu có thời gian), bạn có thể nên chọn nhiều hơn về mức độ bạn quét để tải trước vào bộ nhớ, cho phép phần còn lại được tải từ đĩa theo yêu cầu.


Tại sao bạn cần toàn vẹn giao dịch cho cơ sở dữ liệu trong bộ nhớ? Nếu mất điện, dù sao bạn cũng sẽ mất tất cả.
osa

@osa: giả sử nó cho phép truy cập đồng thời thay vì tuần tự hóa mọi thứ, bạn sẽ muốn một số hình thức quản lý toàn vẹn cho điều đó.
David Spillett

14

Có rất nhiều trường hợp không sử dụng công cụ lưu trữ bộ nhớ - và khi InnoDB sẽ nhanh hơn. Bạn chỉ cần suy nghĩ về đồng thời và không phải các thử nghiệm đơn luồng đơn lẻ.

Nếu bạn có một vùng đệm đủ lớn, thì InnoDB cũng sẽ trở thành cư dân bộ nhớ hoàn toàn cho các hoạt động đọc. Cơ sở dữ liệu có bộ nhớ cache . Họ sưởi ấm bản thân!

Ngoài ra - đừng đánh giá thấp giá trị của khóa cấp hàng và MVCC (độc giả không chặn nhà văn). Nó có thể "chậm hơn" khi ghi phải tiếp tục vào đĩa. Nhưng ít nhất bạn sẽ không bị chặn trong quá trình ghi đó giống như bạn sẽ ở trên bảng nhớ (không có MVCC; khóa cấp bảng).


3

Đối với hồ sơ. Tôi đã thử nghiệm các bảng Mysql trong Bộ nhớ để lưu trữ một số thông tin. Và tôi đã thử nghiệm APC (APCu) của PHP để lưu trữ thông tin tương tự.

Đối với 58000 đăng ký. (varchar + số nguyên + ngày).

  1. Thông tin gốc 24mb ở định dạng văn bản (định dạng csv).
  2. APC của PHP sử dụng 44,7mb RAM.
  3. Bảng của Mysql sử dụng 575mb RAM.

Bảng chỉ có một chỉ mục duy nhất vì vậy tôi không nghĩ rằng đó là yếu tố chính.

Phần kết luận:

Bảng bộ nhớ không phải là một tùy chọn cho các bảng "lớn" vì nó sử dụng quá nhiều bộ nhớ.


2
Đây là một câu trả lời đơn giản. Công cụ lưu trữ MEMORY có thể được điều chỉnh bằng cách sử dụng các loại dữ liệu nhỏ hơn, xác định rõ ràng BTREE là loại chỉ mục và giới hạn lượng dữ liệu được tải vào RAM. Nó vẫn là một lựa chọn khả thi cho các bộ nhỏ hơn. Ngoài ra còn có các yếu tố khác như I / O đĩa tích cực. Xem bài viết của tôi dba.stackexchange.com/questions/6156/...dba.stackexchange.com/questions/2868/... )
RolandoMySQLDBA

Trên thực tế, tôi đã kiểm tra việc thay đổi chỉ mục (và thậm chí xóa hoàn toàn) và kích thước không thay đổi quá nhiều (bao gồm cả việc xây dựng lại bảng từ đầu). IMHO Mysql đang làm một cái gì đó dưới mui xe, có thể là một số loại tối ưu hóa hoặc phân bổ kích thước lớn nhất trên mỗi cột (chẳng hạn trong một varchar).
magallanes

6
Lý do gần như chắc chắn là do VARCHAR của bạn: "MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length." dev.mysql.com/doc/refman/5.6/en/memory-st Storage-engine.html Hiệu quả sẽ xuất hiện VARCHAR trở thành CHAR với công cụ MEMORY.
Matthew1471

2

Nhược điểm khác của các bảng dựa trên BỘ NHỚ là chúng không thể được gọi nhiều lần trong cùng một truy vấn. Ít nhất hành vi đó đã được tìm thấy cho đến phiên bản 5.4. Làm thế nào với CTE (kể từ v8.x), không cần sử dụng các bảng trung gian dựa trên mem cho các thủ tục phức tạp.


1

Theo hướng dẫn sử dụng MySQL và MariaDB, BLOB và CLOB (các loại văn bản khác nhau) không được hỗ trợ bởi bộ lưu trữ NHỚ. Đối với mục đích riêng của chúng tôi, điều này làm cho công cụ lưu trữ MEMOR gần như vô dụng.

http://dev.mysql.com/doc/refman/5.7/en/memory-st Storage-engine.html

Các bảng NHỚ không thể chứa các cột BLOB hoặc văn bản.

https://mariadb.com/kb/en/mariadb/memory-st Storage-engine /

Các loại độ dài thay đổi như VARCHAR có thể được sử dụng trong các bảng NHỚ. Các cột BLOB hoặc văn bản không được hỗ trợ cho các bảng NHỚ.

Khi cố gắng chuyển đổi chỉ một phần cơ sở dữ liệu thành bộ nhớ MEMOR, tôi thấy rằng các khóa ngoại của công cụ lưu trữ không được hỗ trợ. Vì vậy, tất cả các bảng, có tham chiếu khóa ngoài đến các bảng, có chứa BLOB / CLOB cũng phải ở dạng lưu trữ không có bộ nhớ (ít nhất, điều này ảnh hưởng đến các bảng con InnoDB).


1

Các bảng NHỚ không dành cho việc lưu trữ liên tục, đặc biệt là các tập hợp dữ liệu lớn hoặc bất cứ điều gì mà việc lưu giữ là rất quan trọng. Mục đích tốt nhất của họ theo kinh nghiệm của tôi là lưu trữ các bản ghi tạm thời trong quá trình tạo và dân số các bảng tạm thời trong các quy trình phức tạp, thực hiện nhanh hơn đáng kể so với hầu hết các loại bảng khác cho mục đích này với điều kiện ngưỡng đệm chính của bạn cho động cơ được đặt đủ cao để không phát sinh một đĩa ghi. Điều này có thể vận hành một trật tự cường độ nhanh hơn MyISAM hoặc InnoDB cho mục đích này vì không có I / O đĩa, và trong trường hợp một bảng được gói gọn trong một thủ tục cụ thể, việc lập chỉ mục và quan hệ không mang nhiều ý nghĩa như chúng nơi mà sự kiên trì được mong đợi.


1

Ngoài các câu trả lời trước. trực tiếp từ hướng dẫn sử dụng MySQL 5.7:

"Hiệu suất MEMOR bị hạn chế bởi sự tranh chấp do thực thi một luồng và chi phí khóa bảng khi xử lý các bản cập nhật. Điều này hạn chế khả năng mở rộng khi tải tăng, đặc biệt đối với các hỗn hợp câu lệnh bao gồm ghi."

... Và đây là một hạn chế rất thực tế. Ví dụ: khi bạn có nhiều phiên cố gắng tạo các bảng tạm thời NHỚ nhanh, luồng đơn có thể gây ra tắc nghẽn hiệu suất nghiêm trọng.

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.