Aracılığıyla paylaş


Birden Çok Etkin Sonuç Kümesi (MARS) Kullanma

Şunlar için geçerlidir:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalitik Platform Sistemi (PDW)Microsoft Fabric'te SQL veritabanı

OLE DB sürücüsünü indirme

SQL Server 2005 (9.x), Veritabanı Motoru'na erişen uygulamalarda birden fazla aktif sonuç kümesi (MARS) desteğini tanıttı. SQL Server'ın önceki sürümlerinde, veritabanı uygulamaları bir bağlantıda birden fazla aktif ifade tutamazdı. SQL Server varsayılan sonuç kümeleri kullanıldığında, uygulama bir batch'teki tüm sonuç setlerini işlemesi veya iptal etmesi gerekiyordu; böylece o bağlantıda başka bir toplu çalışmaya başlayabiliyordu. SQL Server 2005 (9.x), uygulamaların bağlantı başına birden fazla bekleyen talep olmasını ve özellikle bağlantı başına birden fazla aktif varsayılan sonuç setine sahip olmasını sağlayan yeni bir bağlantı özetniteliği tanıttı.

MARS, aşağıdaki yeni yeteneklerle uygulama tasarımını basitleştirir:

  • Uygulamalar birden fazla varsayılan sonuç setini açık tutabilir ve bunlardan okuma yapabilmektedir.

  • Uygulamalar, varsayılan sonuç kümeleri açıkken diğer ilamaları (örneğin, INSERT, UPDATE, DELETE ve stored procedure çağrıları) çalıştırabilir.

MARS kullanan başvurular aşağıdaki yönergeleri faydalı bulacaktır:

  • Varsayılan sonuç kümeleri, tek SQL ifadeleriyle oluşturulan kısa ömürlü veya kısa vadeli sonuç kümeleri için kullanılmalıdır (SELECT, ÇIĞIT ILE DML, RECEIVE, READ METNI VE BENZERI).

  • Sunucu imleçleri, tek SQL ifadeleriyle oluşturulan daha uzun ömürlü veya büyük sonuç kümeleri için kullanılmalıdır.

  • Prosedürel talepler için sonuçların sonuna kadar okuyun, sonuç döndürüp getirmemeleri ve birden fazla sonuç veren gruplar için ise.

  • Mümkün olduğunda, bağlantı özelliklerini değiştirmek ve işlemleri Transact-SQL ifadelerine tercih ederek API çağrılarını kullanmak için kullanın.

  • MARS'ta, eşzamanlı partiler devam ederken oturum kapsamında taklit yasaktır.

Uyarı

Varsayılan olarak, MARS işlevselliği etkin değildir. OLE DB Driver for SQL Server ile SQL Server'a bağlanırken MARS kullanmak için, bunu bir bağlantı dizisi içinde özellikle etkinleştirmeniz gerekir. Daha fazla bilgi için, bu konunun ilerleyen bölümlerinde bulunan OLE DB Driver for SQL Server bölümlerine bakınız.

SQL Server için OLE DB Sürücüsü, bir bağlantıdaki aktif ifade sayısını sınırlamaz.

Aynı anda birden fazla çoklu ifade toplu veya depolanmış prosedürün çalıştırılması gerekmeyen tipik uygulamalar, MARS'ın nasıl uygulandığını anlamadan MARS'tan faydalanır. Ancak, daha karmaşık gereksinimlere sahip uygulamalar bunu dikkate almak zorundadır.

MARS, tek bir bağlantı içinde birden fazla isteğin aralı olarak yürütülmesini sağlar. Yani, bir toplu çalışmaya izin verir ve çalıştırma sırasında diğer isteklerin yürütülmesine izin verir. Ancak unutmayın ki, MARS paralel uygulama açısından değil, interleaving olarak tanımlanmıştır.

MARS altyapısı, birden fazla partinin aralı bir şekilde çalıştırılmasına izin verir, ancak yürütme yalnızca iyi tanımlanmış noktalarda değiştirilebilir. Ayrıca, çoğu ifade bir grup içinde atomik olarak çalışmak zorundadır. İstemciye satır döndüren ve bazen yield points olarak adlandırılan ifadeler, satırlar istemciye gönderilirken tamamlanmadan önce yürütmeyi birbirine aralarına sokmalarına izin verilir, örneğin:

  • SELECT

  • FETCH

  • RECEIVE

Depolanan bir prosedür veya toplu bölüm olarak çalıştırılan diğer tüm ifadeler, diğer MARS isteklerine aktarılabilmek için tamamlanana kadar çalıştırılmalıdır.

Toplu çalışmaların tam olarak nasıl birbirleriyle yapıldığı bir dizi faktörden etkilenir ve verim puanı içeren birden fazla partiden gelen komutların tam olarak hangi sırada çalıştırılacağını tahmin etmek zordur. Bu karmaşık partilerin aralıklı uygulanması nedeniyle istenmeyen yan etkilerden kaçınmaya dikkat edin.

Bağlantı durumu (SET, USE) ve işlemleri (BEGIN TRAN, COMMIT, ROLLBACK) yönetmek için Transact-SQL ifadeleri yerine API çağrıları kullanarak sorunlardan kaçının; bu ifadeleri çok imalı toplu toplu gruplara dahil etmeyerek, ayrıca tüm sonuçları tüketerek veya iptal ederek bu tür grupların yürütülmesini seri olarak gerçekleştirebilirsiniz.

Uyarı

MARS etkinleştirildiğinde manuel veya örtük bir işlem başlatan bir toplu veya saklanan prosedür, toplu işlemden önce işlemi tamamlamalıdır. Eğer çalışmazsa, SQL Server toplu işlem bittiğinde yapılan tüm değişiklikleri geri alır. Böyle bir işlem, SQL Server tarafından toplu kapsamlı bir işlem olarak yönetilir. Bu, SQL Server 2005 (9.x) ile tanıtılan yeni bir işlem türüdür ve MARS etkinleştirildiğinde mevcut iyi davranan depolanmış prosedürlerin kullanılmasını sağlar. Parti kapsamlı işlemler hakkında daha fazla bilgi için Transaction Statement'a (Transact-SQL) bakınız.

ADO'dan MARS kullanımı örneği için SQL Server için OLE DB Driver ile ADO Kullanımı bölümüne bakınız.

Bellek İçi OLTP

Bellek içi OLTP, sorgular ve yerel derlenmiş depolanmış prosedürler kullanarak MARS'i destekler. MARS, yeni bir sonuç kümesinden satır almak için bir talep göndermeden önce her bir sonuç kümesini tamamen geri almak zorunda kalmadan birden fazla sorgudan veri talep etmeyi sağlar. Birden fazla açık sonuç setinden başarılı okumak için MARS etkin bir bağlantı kullanmanız gerekir.

MARS varsayılan olarak devre dışı bırakılmıştır, bu yüzden bağlantı dizisine eklemek MultipleActiveResultSets=True için açıkça etkinleştirmeniz gerekir. Aşağıdaki örnek, bir SQL Server örneğine nasıl bağlanacağınızı ve MARS'ın etkin olduğunu nasıl belirtileceğini gösterir:

Data Source=MSSQL; Initial Catalog=AdventureWorks; Integrated Security=SSPI; MultipleActiveResultSets=True  

OLTP'In-Memory ile MARS, SQL motorunun geri kalanındaki MARS ile esasen aynıdır. Aşağıda, bellek optimize edilmiş tablolarda ve yerel derlenmiş depolanmış işlemlerde MARS kullanılırken gösterilen farklar listelenmektedir.

MARS ve bellek optimize edilmiş tablolar

MARS etkin bağlantı kullanıldığında disk tabanlı ve bellek optimize edilmiş tablolar arasındaki farklar şunlardır:

  • İki ifade aynı hedef nesnedeki veriyi değiştirebilir, ancak her ikisi de aynı kaydı değiştirmeye çalışırsa, yazma-yazma çatışması yeni işlemin başarısız olmasına yol açar. Ancak, her iki işlem farklı kayıtları değiştirirse, işlemler başarılı olur.

  • Her ifade SNAPSHOT izolasyonu altında çalışır, böylece yeni işlemler mevcut ifadelerin yaptığı değişiklikleri göremez. Eşzamanlı ifadeler aynı işlem altında çalıştırılsa bile, SQL motoru her bir ifade için birbirinden izole olan toplu kapsamlı işlemler oluşturur. Ancak, toplu kapsamlı işlemler hâlâ birbirine bağlıdır, bu yüzden bir toplu kapsamlı işlemlerin geri alınması, aynı partideki diğer işlemleri etkiler.

  • DDL işlemlerine kullanıcı işlemlerine izin verilmediği için hemen başarısız olurlar.

MARS ve yerel derlenmiş depolanmış prosedürler

Yerel derlenmiş depolanmış prosedürler MARS etkin bağlantılarda çalışabilir ve yalnızca bir akım noktası karşılaşıldığında başka bir ifadeye çalıştırma sağlayabilir. Bir verim noktası, yerel derlenmiş bir depolanmış prosedür içinde başka bir ifadeye yürütme sağlayabilen tek ifade olan SELECT ifadesi gerektirir. Eğer prosedürde bir SELECT ifadesi yoksa, vermez, diğer imalar başlamadan önce tamamlanır.

MARS ve Bellek İçi OLTP işlemleri

Aralıklı ifade ve atom blokları ile yapılan değişiklikler birbirinden izole edilir. Örneğin, bir ifade veya atomik blok bazı değişiklikler yaparsa ve ardından başka bir ifadeye yürütülürse, yeni ifade ilk ifadede yapılan değişiklikleri görmez. Ayrıca, ilk ifade tekrar yürütüldüğünde, diğer ifadelerde yapılan değişiklikleri görmez. Açıklamalar yalnızca açıklama başlamadan önce tamamlanıp yapılan değişiklikleri görecektir.

Yeni bir kullanıcı işlemi, mevcut kullanıcı işleminde BEGIN TRANSACTION ifadesi kullanılarak başlatılabilir - bu sadece etkileşimli modda desteklenir, böylece BEGIN TRANSACTION yalnızca bir T-SQL ifadesinden çağrılabilir, yerel derlenmiş bir depolanmış prosedür içinden çağrılamaz. SAVE TRANSACTION veya API çağrısı kullanarak bir işlemde bir kayıt noktası oluşturabilirsiniz. Kaydet(save_point_name) kaydetme noktasına geri dönmek için. Bu özellik yalnızca T-SQL ifadelerinden etkinleştirilir ve yerel derlenmiş depolanmış prosedürler içinden değil.

MARS ve columnstore indeksleri

SQL Server (2016'dan itibaren) MARS'ı columnstore indeksleriyle desteklemektedir. SQL Server 2014, columnstore indeksine sahip tablolara yalnızca okunan bağlantılar için MARS kullanır. Ancak, SQL Server 2014, sütun deposu indeksi olan bir tabloda eşzamanlı veri işleme dili (DML) işlemleri için MARS'ı desteklememektedir. Bu gerçekleştiğinde, SQL Server bağlantıları sonlandırır ve işlemleri iptal eder. SQL Server 2012'de yalnızca okunabilir columnstore indeksleri vardır ve MARS bunlara uygulanmaz.

SQL Server için OLE DB Sürücüsü

SQL Server için OLE DB Sürücüsü, DBPROPSET_SQLSERVERDBINIT özellik setinde uygulanan SSPROP_INIT_MARSCONNECTION veri kaynağı başlatma özelliğinin eklenmesiyle MARS'ı destekler. Ayrıca, yeni bir bağlantı dizisi anahtar kelimesi olan MarsConn eklenmiştir. Doğru veya yanlış değerleri kabul eder; yanlış varsayılan durumdur.

Veri kaynağı özelliği DBPROP_MULTIPLECONNECTIONS varsayılan olarak VARIANT_TRUE olur. Bu, sağlayıcının birden fazla eşzamanlı komut ve satır kümesi nesnesini desteklemek için birden fazla bağlantı oluşturacağı anlamına gelir. MARS etkin olduğunda, SQL Server için OLE DB Driver tek bir bağlantıda birden fazla komut ve satır kümesi nesnesini destekleyebilir, bu yüzden MULTIPLE_CONNECTIONS varsayılan olarak VARIANT_FALSE olarak ayarlanır.

DBPROPSET_SQLSERVERDBINIT özellik kümesine yapılan geliştirmeler hakkında daha fazla bilgi için Başlatma ve Yetkilendirme Özellikleri bölümlerine bakınız.

SQL Server için OLE DB Sürücüsü Örneği

Bu örnekte, bir veri kaynağı nesnesi SQL Server için OLE DB Sürücüsü kullanılarak oluşturulur ve oturum nesnesi oluşturulmadan önce DBPROPSET_SQLSERVERDBINIT özellik seti kullanılarak MARS etkinleştirilir.

#include <msoledbsql.h>  
  
IDBInitialize *pIDBInitialize = NULL;  
IDBCreateSession *pIDBCreateSession = NULL;  
IDBProperties *pIDBProperties = NULL;  
  
// Create the data source object.  
hr = CoCreateInstance(CLSID_MSOLEDBSQL, NULL,  
   CLSCTX_INPROC_SERVER,  
   IID_IDBInitialize,   
    (void**)&pIDBInitialize);  
  
hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties);  
  
// Set the MARS property.  
DBPROP rgPropMARS;  
  
// The following is necessary since MARS is off by default.  
rgPropMARS.dwPropertyID = SSPROP_INIT_MARSCONNECTION;  
rgPropMARS.dwOptions = DBPROPOPTIONS_REQUIRED;  
rgPropMARS.dwStatus = DBPROPSTATUS_OK;  
rgPropMARS.colid = DB_NULLID;  
V_VT(&(rgPropMARS.vValue)) = VT_BOOL;  
V_BOOL(&(rgPropMARS.vValue)) = VARIANT_TRUE;  
  
// Create the structure containing the properties.  
DBPROPSET PropSet;  
PropSet.rgProperties = &rgPropMARS;  
PropSet.cProperties = 1;  
PropSet.guidPropertySet = DBPROPSET_SQLSERVERDBINIT;  
  
// Get an IDBProperties pointer and set the initialization properties.  
pIDBProperties->SetProperties(1, &PropSet);  
pIDBProperties->Release();  
  
// Initialize the data source object.  
hr = pIDBInitialize->Initialize();  
  
//Create a session object from a data source object.  
IOpenRowset * pIOpenRowset = NULL;  
hr = IDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&pIDBCreateSession));  
hr = pIDBCreateSession->CreateSession(  
   NULL,             // pUnkOuter  
   IID_IOpenRowset,  // riid  
  &pIOpenRowset ));  // ppSession  
  
// Create a rowset with a firehose mode cursor.  
IRowset *pIRowset = NULL;  
DBPROP rgRowsetProperties[2];  
  
// To get a firehose mode cursor request a   
// forward only read only rowset.  
rgRowsetProperties[0].dwPropertyID = DBPROP_IRowsetLocate;  
rgRowsetProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[0].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[0].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[0].vValue));  
rgRowsetProperties[0].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[0].vValue.boolVal = VARIANT_FALSE;  
  
rgRowsetProperties[1].dwPropertyID = DBPROP_IRowsetChange;  
rgRowsetProperties[1].dwOptions = DBPROPOPTIONS_REQUIRED;  
rgRowsetProperties[1].dwStatus = DBPROPSTATUS_OK;  
rgRowsetProperties[1].colid = DB_NULLID;  
VariantInit(&(rgRowsetProperties[1].vValue));  
rgRowsetProperties[1].vValue.vt = VARIANT_BOOL;  
rgRowsetProperties[1].vValue.boolVal = VARIANT_FALSE;  
  
DBPROPSET rgRowsetPropSet[1];  
rgRowsetPropSet[0].rgProperties = rgRowsetProperties  
rgRowsetPropSet[0].cProperties = 2  
rgRowsetPropSet[0].guidPropertySet = DBPROPSET_ROWSET;  
  
hr = pIOpenRowset->OpenRowset (NULL,  
   &TableID,  
   NULL,  
   IID_IRowset,  
   1,  
   rgRowsetPropSet  
   (IUnknown**)&pIRowset);  

Ayrıca Bkz.

SQL Server Özellikleri için OLE DB Driver