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

SQL Server - đánh giá tham số

Điều đó tốt nhưng đôi khi có thể xấu.

Đánh giá tham số là về trình tối ưu hóa truy vấn sử dụng giá trị của tham số được cung cấp để tìm ra kế hoạch truy vấn tốt nhất có thể. Một trong nhiều lựa chọn và khá dễ hiểu là nếu toàn bộ bảng nên được quét để lấy các giá trị hoặc nếu nó sẽ nhanh hơn bằng cách sử dụng tìm kiếm chỉ mục. Nếu giá trị trong tham số của bạn có tính chọn lọc cao, trình tối ưu hóa có thể sẽ xây dựng một kế hoạch truy vấn với các tìm kiếm và nếu không, truy vấn sẽ thực hiện quét bảng của bạn.

Kế hoạch truy vấn sau đó được lưu vào bộ nhớ cache và sử dụng lại cho các truy vấn liên tiếp có các giá trị khác nhau. Phần không tốt của việc dò tìm tham số là khi kế hoạch đã lưu trong bộ nhớ cache không phải là lựa chọn tốt nhất cho một trong những giá trị đó.

Dữ liệu mẫu:

create table T
(
  ID int identity primary key,
  Value int not null,
  AnotherValue int null
);

create index IX_T_Value on T(Value);

insert into T(Value) values(1);

insert into T(Value)
select 2
from sys.all_objects;

T là một bảng có vài nghìn hàng với chỉ mục không được phân cụm trên Giá trị. Có một hàng có giá trị là 1 và phần còn lại có giá trị 2 .

Truy vấn mẫu:

select *
from T 
where Value = @Value;

Các lựa chọn mà trình tối ưu hóa truy vấn có ở đây là thực hiện Quét chỉ mục theo cụm và kiểm tra mệnh đề where so với mọi hàng hoặc sử dụng Tìm kiếm chỉ mục để tìm đến các hàng phù hợp và sau đó thực hiện Tra cứu khóa để nhận các giá trị từ các cột được yêu cầu trong danh sách cột.

Khi giá trị được đánh hơi là 1 kế hoạch truy vấn sẽ giống như sau:

Và khi giá trị được đánh hơi là 2 nó sẽ trông như thế này:

Phần không tốt của đánh giá tham số trong trường hợp này xảy ra khi kế hoạch truy vấn được xây dựng đánh hơi 1 nhưng được thực thi sau đó với giá trị là 2 .

Bạn có thể thấy rằng Key Lookup đã được thực hiện 2352 lần. Quét rõ ràng sẽ là lựa chọn tốt hơn.

Tóm lại, tôi muốn nói rằng đánh giá tham số là một điều tốt mà bạn nên cố gắng thực hiện càng nhiều càng tốt bằng cách sử dụng các tham số cho các truy vấn của mình. Đôi khi, nó có thể bị sai và trong những trường hợp đó, rất có thể là do dữ liệu bị sai lệch đang làm xáo trộn số liệu thống kê của bạn.

Cập nhật:

Đây là một truy vấn đối với một số dmv mà bạn có thể sử dụng để tìm truy vấn nào đắt nhất trên hệ thống của mình. Thay đổi thứ tự theo mệnh đề để sử dụng các tiêu chí khác nhau về những gì bạn đang tìm kiếm. Tôi nghĩ rằng TotalDuration là một nơi tốt để bắt đầu.

set transaction isolation level read uncommitted;

select top(10)
  PlanCreated       = qs.creation_time,
  ObjectName        = object_name(st.objectid),
  QueryPlan         = cast(qp.query_plan as xml),
  QueryText         = substring(st.text, 1 + (qs.statement_start_offset / 2), 1 + ((isnull(nullif(qs.statement_end_offset, -1), datalength(st.text)) - qs.statement_start_offset) / 2)),
  ExecutionCount    = qs.execution_count,
  TotalRW           = qs.total_logical_reads + qs.total_logical_writes,
  AvgRW             = (qs.total_logical_reads + qs.total_logical_writes) / qs.execution_count,
  TotalDurationMS   = qs.total_elapsed_time / 1000,
  AvgDurationMS     = qs.total_elapsed_time / qs.execution_count / 1000,
  TotalCPUMS        = qs.total_worker_time / 1000,
  AvgCPUMS          = qs.total_worker_time / qs.execution_count / 1000,
  TotalCLRMS        = qs.total_clr_time / 1000,
  AvgCLRMS          = qs.total_clr_time / qs.execution_count / 1000,
  TotalRows         = qs.total_rows,
  AvgRows           = qs.total_rows / qs.execution_count
from sys.dm_exec_query_stats as qs
  cross apply sys.dm_exec_sql_text(qs.sql_handle) as st
  cross apply sys.dm_exec_text_query_plan(qs.plan_handle, qs.statement_start_offset, qs.statement_end_offset) as qp
--order by ExecutionCount desc
--order by TotalRW desc
order by TotalDurationMS desc
--order by AvgDurationMS desc
;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tại sao kiểu DATETIME của SQL Server tiết kiệm thời gian trong tích tắc 1/300 giây?

  2. Bảng lịch sử SQL Server - điền thông qua SP hoặc Trigger?

  3. Kích hoạt để ngăn Chèn cho dữ liệu trùng lặp của hai cột

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

  5. Cách gắn / mở khóa truy vấn Windows và các tab khác trong SQL Server Management Studio (SSMS) - Hướng dẫn SQL Server / TSQL Phần 21