Đối với một kế hoạch được sử dụng lại tất cả các thuộc tính trong sys.dm_exec_plan_attributes
đó is_cache_key=1
phải giống nhau. Một danh sách này là dưới đây.
acceptable_cursor_options
compat_level
date_first
date_format
dbid
dbid_execute
is_replication_specific
language_id
merge_action_type
objectid
optional_clr_trigger_dbid
optional_clr_trigger_objid
optional_spid
required_cursor_options
set_options
status
user_id
Một trong những ảnh hưởng bằng cách sử dụng hai tên phần là user_id
Nếu bạn thử những điều sau dưới thông tin đăng nhập của người dùng với lược đồ mặc định dbo
DBCC FREEPROCCACHE;
CREATE TABLE dbo.FooBar(X int);
EXEC('SELECT * FROM FooBar');
EXEC('SELECT * FROM FooBar');
EXEC('SELECT * FROM dbo.FooBar');
EXEC('SELECT * FROM dbo.FooBar');
Và sau đó thực hiện các truy vấn sau đây
SELECT usecounts,
text,
value AS [user_id]
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
WHERE text LIKE 'SELECT * FROM %FooBar' and attribute='user_id'
Bạn sẽ thấy kết quả như sau
usecounts text user_id
----------- ----------------------------------- -------
2 SELECT * FROM dbo.FooBar -2
2 SELECT * FROM FooBar 1
Điều này cho thấy cả hai kế hoạch đã được sử dụng lại khi câu lệnh giống hệt được chạy lần thứ hai. Các tài liệu cho sys.dm_exec_plan_attribut giải thích chouser_id
Giá trị -2 chỉ ra rằng lô được gửi không phụ thuộc vào độ phân giải tên ẩn và có thể được chia sẻ giữa những người dùng khác nhau. Đây là phương pháp ưa thích. Bất kỳ giá trị nào khác đại diện cho ID người dùng của người dùng gửi truy vấn trong cơ sở dữ liệu.
Điều này dường như là không chính xác! Dường như từ thử nghiệm của tôi, giá trị mà nó thực sự sử dụng cho user_id
trường hợp thứ hai là schema_id
lược đồ mặc định cho người dùng thực thi thay vì định danh cho người dùng cụ thể đó. Chạy lại bốn EXEC
câu lệnh dưới một thông tin đăng nhập khác với lược đồ mặc định "dbo" đưa ra.
usecounts text user_id
----------- ----------------------------------- -------
4 SELECT * FROM dbo.FooBar -2
4 SELECT * FROM FooBar 1
Hiển thị các gói cho cả hai phiên bản truy vấn có thể được sử dụng lại giữa những người dùng. Cuối cùng chạy lại bốn EXEC
câu lệnh dưới lần đăng nhập thứ ba với lược đồ mặc định "khách" đưa ra.
usecounts text user_id
----------- ----------------------------------- -------
6 SELECT * FROM dbo.FooBar -2
4 SELECT * FROM FooBar 1
2 SELECT * FROM FooBar 2
Cho thấy rằng kế hoạch cho dbo
truy vấn đủ điều kiện đã được chia sẻ thành công giữa những người dùng với các lược đồ mặc định khác nhau nhưng truy vấn không đủ điều kiện lược đồ cần một kế hoạch mới được biên dịch.
Nếu bạn không thấy chia sẻ này xảy ra đảm bảo rằng tất cả các thông tin đăng nhập bạn đang thử nghiệm có cùng set_options
, language_id
, date_first
, date_format
vì đây là một trong những chìa khóa bộ nhớ cache được liệt kê ở đầu và bất kỳ sự khác biệt trong những sẽ ngăn chặn các kế hoạch được tái sử dụng giữa các phiên.
user_id
. Trong thử nghiệm ban đầu của tôi, tôi đã có người dùng thứ haiWITH DEFAULT_SCHEMA=[guest]
. Miễn là hai người dùng khác nhau có cùng một lược đồ mặc định, có vẻ như họ có thể chia sẻ các gói của nhau.