Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cải thiện hiệu suất truy vấn SQL Server trên các bảng lớn

Câu trả lời đơn giản:KHÔNG. Bạn không thể trợ giúp các truy vấn đặc biệt trên bảng 238 cột với Hệ số lấp đầy 50% trên Chỉ mục được phân nhóm.

Câu trả lời chi tiết:

Như tôi đã nêu trong các câu trả lời khác về chủ đề này, Thiết kế chỉ mục vừa là Nghệ thuật vừa là Khoa học và có rất nhiều yếu tố cần xem xét đến mức có rất ít quy tắc cứng và nhanh, nếu có. Bạn cần xem xét:khối lượng hoạt động DML so với SELECT, hệ thống con đĩa, các chỉ mục / trình kích hoạt khác trên bảng, phân phối dữ liệu trong bảng, là các truy vấn sử dụng điều kiện SARGable WHERE và một số điều khác mà tôi thậm chí không thể nhớ được. bây giờ.

Tôi có thể nói rằng không thể trợ giúp cho các câu hỏi về chủ đề này nếu không hiểu về Bảng, các chỉ mục, trình kích hoạt của nó, v.v. Bây giờ bạn đã đăng định nghĩa bảng (vẫn đang chờ Chỉ mục nhưng riêng định nghĩa Bảng chỉ đến 99% vấn đề) Tôi có thể đưa ra một số gợi ý.

Đầu tiên, nếu định nghĩa bảng là chính xác (238 cột, 50% Hệ số lấp đầy) thì bạn có thể bỏ qua phần còn lại của câu trả lời / lời khuyên ở đây;-). Xin lỗi vì không mang tính chính trị ở đây, nhưng nghiêm túc mà nói, đó là một cuộc rượt đuổi ngỗng hoang mà không biết chi tiết cụ thể. Và bây giờ chúng ta thấy định nghĩa bảng, nó trở nên rõ ràng hơn một chút về lý do tại sao một truy vấn đơn giản lại mất nhiều thời gian như vậy, ngay cả khi các truy vấn thử nghiệm (Bản cập nhật # 1) chạy quá nhanh.

Vấn đề chính ở đây (và trong nhiều tình huống hoạt động kém) là mô hình dữ liệu không tốt. 238 cột không bị cấm cũng giống như việc có 999 chỉ mục không bị cấm, nhưng nói chung là không khôn ngoan lắm.

Khuyến nghị:

  1. Đầu tiên, bảng này thực sự cần được sửa sang lại. Nếu đây là một bảng kho dữ liệu thì có thể, nhưng nếu không thì các trường này thực sự cần được chia thành nhiều bảng mà tất cả có thể có cùng PK. Bạn sẽ có một bảng bản ghi chính và các bảng con chỉ là thông tin phụ thuộc dựa trên các thuộc tính thường được kết hợp và PK của các bảng đó giống với PK của bảng chính và do đó cũng FK với bảng chính. Sẽ có mối quan hệ 1-1 giữa bảng cái và tất cả các bảng con.
  2. Việc sử dụng ANSI_PADDING OFF là đáng lo ngại, chưa kể đến sự không nhất quán trong bảng do các cột bổ sung khác nhau theo thời gian. Không chắc liệu bạn có thể khắc phục điều đó ngay bây giờ hay không, nhưng lý tưởng nhất là bạn sẽ luôn có ANSI_PADDING ON hoặc ít nhất có cùng một cài đặt trên tất cả ALTER TABLE tuyên bố.
  3. Cân nhắc tạo 2 Nhóm Tệp bổ sung:Bảng và Chỉ mục. Tốt nhất là không đặt nội dung của bạn vào CHÍNH vì đó là nơi SQL SERVER lưu trữ tất cả dữ liệu của nó và siêu dữ liệu về các đối tượng của bạn. Bạn tạo Bảng và Chỉ mục theo cụm của mình (vì đó là dữ liệu cho bảng) trên [Tables] và tất cả các chỉ mục Không được phân cụm trên [Indexes]
  4. Tăng Hệ số lấp đầy từ 50%. Con số thấp này có thể là lý do tại sao không gian chỉ mục của bạn lớn hơn không gian dữ liệu của bạn. Thực hiện Xây dựng lại chỉ mục sẽ tạo lại các trang dữ liệu có tối đa 4k (trong tổng số 8 nghìn trang) được sử dụng cho dữ liệu của bạn để bảng của bạn được trải rộng trên một diện tích rộng.
  5. Nếu hầu hết hoặc tất cả các truy vấn có "ER101_ORG_CODE" trong WHERE điều kiện, sau đó xem xét chuyển điều đó đến cột đầu tiên của chỉ mục được nhóm. Giả sử rằng nó được sử dụng thường xuyên hơn "ER101_ORD_NBR". Nếu "ER101_ORD_NBR" được sử dụng thường xuyên hơn thì hãy giữ nguyên. Có vẻ như, giả sử rằng tên trường có nghĩa là "Mã tổ chức" và "Số thứ tự", thì "Mã tổ chức" là một nhóm tốt hơn có thể có nhiều "Số thứ tự" bên trong nó.
  6. Điểm nhỏ, nhưng nếu "ER101_ORG_CODE" luôn là 2 ký tự, thì hãy sử dụng CHAR (2) thay vì VARCHAR (2) vì nó sẽ lưu một byte trong tiêu đề hàng để theo dõi kích thước chiều rộng thay đổi và thêm hàng triệu hàng.
  7. Như những người khác ở đây đã đề cập, sử dụng SELECT * sẽ ảnh hưởng đến hiệu suất. Không chỉ do nó yêu cầu SQL Server trả về tất cả các cột và do đó có nhiều khả năng thực hiện Quét chỉ mục theo cụm bất kể các chỉ mục khác của bạn, mà còn mất thời gian SQL Server để đi đến định nghĩa bảng và dịch * vào tất cả các tên cột. Nó phải là hơi nhanh hơn để chỉ định tất cả 238 tên cột trong SELECT mặc dù điều đó sẽ không giúp được vấn đề Quét. Nhưng bạn có bao giờ thực sự cần tất cả 238 cột cùng một lúc không?

Chúc bạn thành công!

CẬP NHẬT
Vì lợi ích của sự hoàn chỉnh cho câu hỏi "cách cải thiện hiệu suất trên một bảng lớn cho các truy vấn đặc biệt", cần lưu ý rằng mặc dù nó sẽ không giúp ích gì cho trường hợp cụ thể này, NẾU ai đó đang sử dụng SQL Server 2012 (hoặc mới hơn khi đến thời điểm đó) và NẾU bảng không được cập nhật, thì sử dụng Columnstore Indexes là một tùy chọn. Để biết thêm chi tiết về tính năng mới đó, hãy xem tại đây:http://msdn.microsoft.com/en-us/library/gg492088.aspx (Tôi tin rằng chúng được thiết kế để có thể cập nhật bắt đầu từ SQL Server 2014).

CẬP NHẬT 2
Các cân nhắc bổ sung là:

  • Bật tính năng nén trên Chỉ mục theo cụm. Tùy chọn này có sẵn trong SQL Server 2008, nhưng là một tính năng chỉ dành cho Phiên bản Doanh nghiệp. Tuy nhiên, kể từ SQL Server 2016 SP1 , Nén dữ liệu đã được cung cấp trong tất cả các phiên bản! Vui lòng xem trang MSDN về Nén dữ liệu để biết chi tiết về Nén hàng và trang.
  • Nếu bạn không thể sử dụng Nén dữ liệu hoặc nếu nó không mang lại nhiều lợi ích cho một bảng cụ thể, thì NẾU bạn có một cột thuộc loại độ dài cố định ( INT , BIGINT , TINYINT , SMALLINT , CHAR , NCHAR , BINARY , DATETIME , SMALLDATETIME , MONEY , v.v.) và hơn 50% số hàng là NULL , sau đó xem xét bật SPARSE tùy chọn này có sẵn trong SQL Server 2008. Vui lòng xem trang MSDN để sử dụng các cột thưa thớt để biết thêm chi tiết.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để in VARCHAR (MAX) bằng Print Statement?

  2. varbinary thành chuỗi trên SQL Server

  3. Với (nolock) trong SQL Server là gì?

  4. Kế hoạch thực thi SQL Server - nó là gì và nó giúp giải quyết các vấn đề về hiệu suất như thế nào?

  5. Cách chỉ định vị trí của tệp dữ liệu và tệp nhật ký khi tạo cơ sở dữ liệu trong SQL Server