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

Tại sao Trình tối ưu hóa Truy vấn hoàn toàn bỏ qua các chỉ mục chế độ xem được lập chỉ mục?

tl; dr answer:Nếu bạn không chỉ định NOEXPAND, trình tối ưu hóa truy vấn không biết bạn đang gửi một lựa chọn đơn giản từ một chế độ xem. Nó sẽ phải phù hợp với việc mở rộng truy vấn của bạn (tất cả những gì nó nhìn thấy) với một số chỉ mục chế độ xem. Có lẽ sẽ không bận tâm khi đó là một tham gia năm cách với một loạt các diễn viên.

Xem đối sánh chỉ mục với truy vấn là một vấn đề khó và tôi tin rằng chế độ xem của bạn quá phức tạp để công cụ truy vấn có thể khớp với chỉ mục. Hãy xem xét đây là một trong những truy vấn của bạn:

SELECT ID, Code1 FROM EntityView Where Code1 > 'NR%';

Rõ ràng là bạn có thể sử dụng chỉ mục chế độ xem, nhưng đây không phải là truy vấn mà công cụ truy vấn nhìn thấy. Chế độ xem tự động được mở rộng nếu bạn không chỉ định NOEXPAND, vì vậy đây là những gì chuyển đến công cụ truy vấn:

SELECT ID, Code1 FROM (
    SELECT e.ID, 'NR'+CAST(c1.CODE as nvarchar(11)) as Code1, 'NR'+CAST(c2.CODE as nvarchar(11)) as Code2, 'NR'+CAST(c3.CODE as nvarchar(11)) as Code3, 'NR'+CAST(c4.CODE as nvarchar(11)) as Code4, 'NR'+CAST(c5.CODE as nvarchar(11)) as Code5
    FROM dbo.Entity e
        inner join  dbo.Classificator1 c1 on e.ID = c1.ID
        inner join  dbo.Classificator2 c2 on e.ID = c2.ID
        inner join  dbo.Classificator3 c3 on e.ID = c3.ID
        inner join  dbo.Classificator4 c4 on e.ID = c4.ID
        inner join  dbo.Classificator5 c5 on e.ID = c5.ID;
) AS V;

Công cụ truy vấn thấy truy vấn phức tạp này và nó có thông tin (nhưng có thể không phải là SQL của định nghĩa chế độ xem) mô tả các chỉ mục chế độ xem đã được xác định. Do truy vấn này và các chỉ mục chế độ xem đều có nhiều phép nối và kiểu, nên việc đối sánh là một công việc khó khăn.

Hãy nhớ rằng bạn biết các phép nối và kết hợp giống hệt nhau trong truy vấn này và các chỉ mục chế độ xem, nhưng bộ xử lý truy vấn không biết điều đó. Nó xử lý truy vấn này giống như khi nó kết hợp năm bản sao của Classificator3 hoặc nếu một trong các cột là 'NQ' + CAST (c2.CODE as varchar (12)). Trình so khớp chỉ mục chế độ xem (giả sử nó đã thực hiện bất kỳ nỗ lực nào để đối sánh với một truy vấn phức tạp này) sẽ phải khớp mọi chi tiết của truy vấn này với chi tiết của các chỉ mục chế độ xem trên các bảng có liên quan.

Công cụ truy vấn có mục tiêu số 1 là tìm ra cách thực thi truy vấn một cách hiệu quả. Nó có thể không được thiết kế để dành nhiều thời gian cố gắng khớp mọi chi tiết của phép nối năm cách và CAST với một chỉ mục chế độ xem.

Nếu tôi phải đoán, tôi nghi ngờ trình so khớp chỉ mục xem thấy rằng các cột kết quả của truy vấn thậm chí không phải là các cột của bất kỳ bảng bên dưới nào (vì CAST) và chỉ đơn giản là không bận tâm thử bất cứ điều gì. Đã thêm : Tôi nhầm. Tôi vừa thử đề xuất của Martin về việc cập nhật số liệu thống kê để làm cho truy vấn trở nên đắt đỏ và một chỉ mục chế độ xem được khớp cho một số truy vấn này mà không có NOEXPAND. Trình so khớp chế độ xem thông minh hơn tôi nghĩ! Vì vậy, vấn đề là trình so khớp chế độ xem có thể cố gắng hơn để so khớp một truy vấn phức tạp nếu chi phí của nó rất cao.

Sử dụng gợi ý NOEXPAND thay vì mong đợi công cụ truy vấn có thể tìm ra những gì phù hợp ở đây. NOEXPAND hoàn toàn là bạn của bạn, bởi vì sau đó công cụ truy vấn sẽ nhìn thấy

SELECT ID, Code1 FROM EntityView Where Code1 > 'NR%';

và sau đó rõ ràng ngay lập tức đối với trình so khớp chỉ mục xem rằng có một chỉ mục hữu ích.

(Lưu ý:Mã Fiddle SQL của bạn có tất cả 5 tham chiếu khóa ngoại đến cùng một bảng, đây có thể không phải là điều bạn muốn.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server Chèn số lượng lớn có phải là giao dịch không?

  2. JPA SET IDENTITY_INSERT không hoạt động

  3. Sử dụng SQL Server Express 2008 với cơ sở dữ liệu SQL Server 2005 - cách kiểm tra tính tương thích

  4. Làm thế nào để tạo phiên bản mặc định sau khi tạo một phiên bản được đặt tên?

  5. Chuyển đổi một chuỗi thành int bằng cách sử dụng truy vấn sql