Skenario: SQL Server 2014 (v12.0.4100.1)
Layanan .NET menjalankan kueri ini:
SELECT name, base_object_name
FROM sys.synonyms
WHERE schema_id IN (SELECT schema_id
FROM sys.schemas
WHERE name = N'XXXX')
ORDER BY name
... yang mengembalikan sekitar 6500 baris tetapi sering kali keluar setelah 3+ menit. Di XXXX
atas bukan 'dbo'.
Jika saya menjalankan kueri ini dalam SSMS sebagai UserA, kueri kembali dalam waktu kurang dari satu detik.
Ketika dijalankan sebagai UserB (yang merupakan cara layanan .NET terhubung), kueri membutuhkan waktu 3-6 menit , dan memiliki% CPU sebesar 25% (dari 4 core) sepanjang waktu.
UserA adalah Login Domain dalam peran sysadmin.
UserB adalah SQL Login dengan:
EXEC sp_addrolemember N'db_datareader', N'UserB'
EXEC sp_addrolemember N'db_datawriter', N'UserB'
EXEC sp_addrolemember N'db_ddladmin', N'UserB'
GRANT EXECUTE TO [UserB]
GRANT CREATE SCHEMA TO [UserB]
GRANT VIEW DEFINITION TO [UserB]
Saya bisa menduplikasi ini dalam SSMS dengan membungkus SQL di atas dalam satu Execute as...Revert
blok, sehingga kode .NET keluar dari gambar.
Rencana eksekusi terlihat sama. Saya membuat XML dan hanya ada sedikit perbedaan (CompileTime, CompileCPU, CompileMemory).
Statistik IO semua tidak menunjukkan bacaan fisik:
Nilai tabel 'sysobjes'. Pindai hitungan 0, bacaan logis 19970, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bac baca baca depan 0. Tabel 'Workfile'. Pindai jumlah 0, bacaan logis 0, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bac baca baca-depan 0. Tabel 'Meja Kerja'. Pindai jumlah 0, bacaan logis 0, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bac baca baca-depan 0. Tabel 'sysschobjs'. Pindai hitungan 1, bacaan logis 9122, bacaan fisik 0, bacaan baca depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0. Tabel 'sysclsobjs'. Pindai menghitung 0, bacaan logis 2, bacaan fisik 0, bacaan baca-depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.
Status menunggu XEvent (untuk permintaan ~ 3 menit) adalah:
+ --------------------- + ------------ + -------------- -------- + ------------------------------ + ---------- ------------------- + | Jenis Tunggu | Tunggu Hitungan | Total Waktu Tunggu (ms) | Total Waktu Tunggu Sumberdaya (ms) | Total Waktu Tunggu Sinyal (ms) | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- + | SOS_SCHEDULER_YIELD | 37300 | 427 | 20 | 407 | | NETWORK_IO | 5 | 26 | 26 | 0 | | IO_COMPLETION | 3 | 1 | 1 | 0 | + --------------------- + ------------ + -------------- -------- + ------------------------------- + --------- -------------------- +
Jika saya menulis ulang kueri (dalam SSMS, saya tidak memiliki akses ke Kode Aplikasi) ke
declare @id int
SELECT @id=schema_id FROM sys.schemas WHERE name = N'XXXX'
SELECT a.name, base_object_name FROM sys.synonyms a
WHERE schema_id = @id
ORDER BY name
kemudian UserB berjalan pada kecepatan (cepat) yang sama dengan UserA.
Jika saya menambahkan db_owner
ke UserB, maka, sekali lagi, kueri berjalan <1 detik.
Skema yang dibuat melalui templat ini:
DECLARE @TranName VARCHAR(20)
SELECT @TranName = 'MyTransaction'
BEGIN TRANSACTION @TranName
GO
IF NOT EXISTS (SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = '{1}')
BEGIN
EXEC('CREATE SCHEMA [{1}]')
EXEC sp_addextendedproperty @name='User', @value='{0}', @level0type=N'Schema', @level0name=N'{1}'
END
GO
{2}
COMMIT TRANSACTION MyTransaction;
GO
Dan {2} adalah, saya percaya, daftar Sinonim yang dibuat dalam skema itu.
Profil Permintaan pada dua titik ke dalam permintaan:
Saya sudah membuka tiket dengan Microsoft.
Kami juga mencoba menambahkan UserB ke db_owner
, dan kemudian mengambil DENY
semua hak istimewa yang kami ketahui terkait dengan db_owner
. Hasilnya adalah permintaan yang cepat. Entah kami melewatkan sesuatu (sepenuhnya mungkin), atau ada pemeriksaan khusus untuk db_owner
peran tersebut.