Mặc dù bài đăng này sẽ không phải là một câu trả lời đầy đủ do thiếu thông tin, nhưng nó sẽ có thể chỉ cho bạn đi đúng hướng hoặc có được cái nhìn sâu sắc mà sau này bạn có thể chia sẻ với cộng đồng.
Thật không may, định nghĩa này dẫn đến sự suy giảm hiệu năng liên quan đến tình huống trước đó với một bảng dựa trên đĩa. Thứ tự cường độ cao hơn hoặc thấp hơn 10% (trong một số trường hợp đạt 100%, do đó gấp đôi thời gian).
Trên hết, tôi đã mong đợi sẽ đạt được một siêu lợi thế trong các kịch bản có tính đồng thời cao, với kiến trúc không khóa được quảng cáo bởi Microsoft. Thay vào đó, các màn trình diễn tệ nhất chính xác là khi có một số người dùng đồng thời chạy một số truy vấn trên bàn.
Điều này là rắc rối vì nó chắc chắn không phải là trường hợp. Một số khối lượng công việc nhất định không dành cho các bảng bộ nhớ (SQL 2014) và một số khối lượng công việc tự cho vay. Trong hầu hết các tình huống có thể có một cú va chạm tối thiểu trong hiệu suất chỉ bằng cách di chuyển và chọn các chỉ mục thích hợp.
Ban đầu tôi đã suy nghĩ rất hẹp về các câu hỏi của bạn về vấn đề này:
Câu hỏi:
- BucksET_COUNT chính xác để đặt là gì?
- Tôi nên sử dụng loại chỉ số nào?
- Tại sao hiệu suất kém hơn so với bảng dựa trên đĩa?
Ban đầu tôi tin rằng có một vấn đề với thực tế trong bảng bộ nhớ và các chỉ mục không được tối ưu. Mặc dù có một số vấn đề với định nghĩa chỉ số băm được tối ưu hóa bộ nhớ, tôi tin rằng vấn đề thực sự xảy ra với các truy vấn được sử dụng.
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
Việc chèn này phải cực kỳ nhanh nếu nó chỉ liên quan đến bảng nhớ. Tuy nhiên, nó cũng liên quan đến một bảng dựa trên đĩa và chịu tất cả các khóa và chặn liên quan đến điều đó. Vì vậy, lãng phí thời gian thực ở đây là trên bảng dựa trên đĩa.
Khi tôi thực hiện một thử nghiệm nhanh với 100.000 hàng chèn từ bảng dựa trên đĩa sau khi tải dữ liệu vào bộ nhớ - đó là thời gian phản hồi dưới giây. Tuy nhiên, hầu hết dữ liệu của bạn chỉ được lưu giữ trong một khoảng thời gian rất ngắn, dưới 20 giây. Điều này không cho nó nhiều thời gian để thực sự sống trong bộ nhớ cache. Ngoài ra, tôi không chắc AnotherTable
thực sự lớn đến mức nào và không biết các giá trị có được đọc ra khỏi đĩa hay không. Chúng tôi phải dựa vào bạn cho những câu trả lời.
Với truy vấn Chọn:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1
Một lần nữa, chúng tôi rất hài lòng về hiệu suất bảng dựa trên đĩa + đĩa. Ngoài ra, các loại không rẻ trên các chỉ mục HASH và nên sử dụng một chỉ mục không bao gồm. Điều này được gọi ra trong hướng dẫn Index tôi liên kết trong các ý kiến.
Để đưa ra một số sự kiện dựa trên nghiên cứu thực tế, tôi đã tải SearchItems
vào bảng bộ nhớ với 10 triệu hàng và AnotherTable
với 100.000 vì tôi không biết kích thước hoặc số liệu thống kê thực tế của nó. Sau đó tôi đã sử dụng truy vấn chọn ở trên để thực thi. Ngoài ra, tôi đã tạo một phiên sự kiện mở rộng trên Wait_completed và đặt nó vào bộ đệm vòng. Nó đã được làm sạch sau mỗi lần chạy. Tôi cũng đã chạy DBCC DROPCLEANBUFFERS
để mô phỏng một môi trường nơi tất cả dữ liệu có thể không phải là bộ nhớ cư trú.
Kết quả không có gì ngoạn mục khi nhìn chúng trong chân không. Vì máy tính xách tay mà tôi đang thử nghiệm này đang sử dụng ổ SSD cao cấp hơn, nên tôi đã giảm hiệu năng dựa trên đĩa một cách giả tạo cho VM tôi đang sử dụng.
Các kết quả được đưa ra mà không có thông tin chờ đợi sau 5 lần truy vấn trên bảng dựa trên bộ nhớ (loại bỏ tham gia và không có truy vấn phụ). Điều này là khá nhiều như mong đợi.
Tuy nhiên, khi sử dụng truy vấn ban đầu, tôi đã chờ đợi. Trong trường hợp này, đó là PAGEIOLATCH_SH, có nghĩa là dữ liệu đang được đọc trên đĩa. Vì tôi là người dùng duy nhất trong hệ thống này và không dành thời gian để tạo môi trường thử nghiệm lớn để chèn, cập nhật, xóa đối với bảng đã tham gia, tôi không mong đợi bất kỳ khóa hoặc chặn nào có hiệu lực.
Trong trường hợp này, một lần nữa, phần thời gian đáng kể được dành cho bảng dựa trên đĩa.
Cuối cùng là truy vấn xóa. Việc tìm các hàng dựa trên ID1 không thực sự hiệu quả với chỉ mục có. Mặc dù đúng là các biến vị ngữ bằng là chỉ số băm phù hợp với mục đích nào, nhóm mà dữ liệu rơi vào được dựa trên toàn bộ các cột được băm. Do đó id1, id2 trong đó id1 = 1, id2 = 2 và id1 = 1, id2 = 3 sẽ băm vào các nhóm khác nhau vì hàm băm sẽ nằm ngang (1,2) và (1,3). Đây sẽ không phải là một phạm vi quét B-Tree đơn giản vì các chỉ mục băm không được cấu trúc theo cùng một cách. Sau đó, tôi hy vọng đây không phải là chỉ số lý tưởng cho hoạt động này, tuy nhiên tôi sẽ không mong đợi nó sẽ nhận được các đơn đặt hàng có cường độ lâu hơn như kinh nghiệm. Tôi sẽ quan tâm đến việc xem Wait_info về điều này.
Trên hết, tôi đã mong đợi sẽ đạt được một siêu lợi thế trong các kịch bản có tính đồng thời cao, với kiến trúc không khóa được quảng cáo bởi Microsoft. Thay vào đó, các màn trình diễn tệ nhất chính xác là khi có một số người dùng đồng thời chạy một số truy vấn trên bàn.
Mặc dù đúng là các khóa được sử dụng để thống nhất logic, các thao tác vẫn phải là nguyên tử. Điều này được thực hiện thông qua một toán tử so sánh dựa trên CPU đặc biệt (đó là lý do tại sao In-Memory chỉ hoạt động với một số [mặc dù gần như tất cả các cpus được thực hiện trong 4 năm qua]. Do đó, chúng tôi không nhận được mọi thứ miễn phí, vẫn sẽ có một thời gian để hoàn thành các hoạt động này.
Một điểm khác được đưa ra là trong hầu hết tất cả các truy vấn, giao diện được sử dụng là T-SQL (và không phải là các XUÂN được biên dịch tự nhiên) mà tất cả đều chạm vào ít nhất một bảng dựa trên đĩa. Đây là lý do tại sao tôi tin rằng, cuối cùng, chúng ta thực sự không có bất kỳ hiệu suất tăng nào vì chúng ta vẫn bị hạn chế về hiệu suất của các bảng dựa trên đĩa.
Theo sát:
Tạo một phiên sự kiện mở rộng cho Wait_completed và chỉ định SPID mà bạn biết. Chạy truy vấn và cung cấp cho chúng tôi đầu ra hoặc tiêu thụ nội bộ.
Cung cấp cho chúng tôi cập nhật về đầu ra từ # 1.
Không có số ma thuật để xác định số lượng xô cho các chỉ số băm. Về cơ bản miễn là các thùng không đầy đủ và các chuỗi hàng ở dưới 3 hoặc 4, hiệu suất sẽ ở mức chấp nhận được. Điều này giống như hỏi, "Tôi nên đặt tệp nhật ký của mình thành gì?" - nó sẽ phụ thuộc vào mỗi quy trình, mỗi cơ sở dữ liệu, mỗi loại sử dụng.
OPTION(OPTIMIZE FOR UNKNOWN)
(xem Gợi ý Bảng ) chưa?