(0) exportieren Drucken
Alle erweitern

Leistungsüberlegungen zu Windows Azure SQL-Datenbanken

Letzte Aktualisierung: Januar 2014

In diesem Artikel werden Best Practices für Anwendungen erörtert, durch die die Leistung von Anwendungen verbessert wird, die eine zu Windows Azure SQL-Datenbank migrierte Datenbank verwenden. Wenn sich ein Datenbankserver im selben Rack wie der Anwendungsserver befindet, haben diese Best Practices möglicherweise nur geringe Auswirkungen. Wird der Datenbankserver jedoch in ein Remotedatencenter umgelagert, sind die gleichen Best Practices für die Aufrechterhaltung einer guten Leistung unverzichtbar. Darüber hinaus ist Windows Azure eine freigegebene Umgebung, da alle Ressourcen mit anderen Anwendungen, Rollen und Datenbanken gemeinsam genutzt werden. Windows Azure setzt Netzwerklastenausgleichs- und Gatewaykomponenten ein, um Skaleneffekte zu nutzen und der Umgebung in ihrer Gesamtheit möglichst effizient Rechen- und Netzwerkressourcen zur Verfügung zu stellen. Diese Faktoren sollten beim Anwendungsentwurf und der Anwendungsbereitstellung für Windows Azure berücksichtigt werden.

In diesem Artikel werden Best Practices zum Entwurf und zur Implementierung beschrieben, mit deren Hilfe die Leistung für die Windows Azure SQL-Datenbank-Umgebung optimiert werden kann. In diesem Artikel werden insbesondere Best Practices für zwei Bereiche erörtert, in denen Leistungsprobleme auftreten können, wenn lokale Datenbanken zu Windows Azure SQL-Datenbank migriert werden:

Wie nachfolgend beschrieben, gibt es noch weitere Artikel, in denen die Leistung von Windows Azure-Datenbanken behandelt wird:

Bei Verwendung der aktuell über das Vorschauprogramm verfügbaren Premium Edition bietet die Windows Azure SQL-Datenbank die Möglichkeit, Ressourcen für die Datenbank zu reservieren. Das Whitepaper Leitfaden für die Premium-Vorschau für SQL-Datenbank unterstützt Sie bei der Entscheidung, ob die über das Vorschauprogramm verfügbare Premium-Datenbank für Ihre Anwendung geeignet ist, und enthält Empfehlungen dazu, wie Sie Ihre Anwendung optimieren, um die Leistungsfähigkeit dieser Funktion voll auszuschöpfen.

Im Artikel Windows Azure SQL-Datenbank und SQL Server – Vergleich und Gegenüberstellung der Leistung und Skalierbarkeit werden verschiedene Leistungsmuster für die SQL-Datenbank sowie Verfahren zur richtigen Leistungsbewertung beschrieben. Außerdem sind einige SQL-Skripts enthalten, die Sie dabei unterstützen, SQL-Datenbankinstanzen auszuwerten und Probleme mit diesen Instanzen zu beheben.

  • Verbindungsverwaltung

  • Netzwerklatenz zwischen der Anwendungsebene und der Datenbankebene

Autoren: Silvano Coriani, Steve Howard
Bearbeiter: Mark Simms, Valery Mizonov, Kun Cheng, Paolo Salvatori, Jaime Alva Bravo

Verbindungsverwaltung in Windows Azure SQL-Datenbank

Wenn eine Datenbank in Windows Azure SQL-Datenbank gehostet wird, können Datenbankverbindungen häufiger als in einer lokalen Umgebung getrennt werden. Benutzer nehmen diese Unterbrechungen u. U. als Leistungsproblem wahr, wenn der Verbindungsverlust bei einem vorübergehenden Fehler von Anwendungen nicht schnell erkannt und eine neue Verbindung hergestellt wird. Windows Azure SQL-Datenbank ist Anbieter eines umfangreichen mehrinstanzenfähigen Datenbankdiensts auf freigegebenen Ressourcen. Um allen Mandanten eine leistungsfähige Umgebung zu bieten, werden alle Datenbanken über drei Knoten gruppiert und Ressourcen gleichmäßig zwischen Clusterknoten verteilt. Ein vorübergehender Fehler liegt z. B. dann vor, wenn in Windows Azure SQL-Datenbank ein stark beanspruchter Server erkannt wird, auf dem mehrere Datenbanken gehostet werden. In diesem Fall kann Windows Azure SQL-Datenbank für eine der Datenbanken ein Failover auf einen sekundären Clusterknoten ausführen, der eine geringere Verarbeitungslast aufweist. Beim Failover werden alle geöffneten Verbindungen mit der Datenbank beendet und ein Rollback für ausstehende Transaktionen ausgeführt. Die Anwendungen müssen den Fehler schnell erkennen, erneut eine Verbindung mit der Datenbank herstellen und die zuletzt ausgeführte Transaktion wiederholen.

In der folgenden Liste sind einige Gründe dafür aufgelistet, warum Verbindungen von Windows Azure SQL-Datenbank beendet werden können:

  • Die gesamte Netzwerktopologie von Windows Azure SQL-Datenbank enthält Firewalls, Lastenausgleichsmodule sowie TDS-Gateways (Tabular Data Stream). Durch jede dieser Topologiekomponenten wird zwischen dem Datenzugriffscode und dem Datenbankknoten eine Schicht hinzugefügt. Fehler in diesen zusätzlichen Schichten können dazu führen, dass Verbindungen beendet werden.

  • In Windows Azure SQL-Datenbank werden kontinuierlich Statistikdaten zur Datenbanknutzung gesammelt und analysiert. Auf Grundlage dieser Statistiken können Verbindungen von Windows Azure SQL-Datenbank falls erforderlich beendet werden, um die Integrität des Diensts aufrechtzuerhalten.

  • Denial-of-Service-Angriffe führen dazu, dass Verbindungen über eine bestimmte IP-Adresse von Windows Azure SQL-Datenbank für einige Zeit blockiert werden.

  • Einige Failoverereignisse können bewirken, dass eine Sitzung in Windows Azure SQL-Datenbank unvermittelt beendet wird. (Beachten Sie, dass Verbindungen, die vor einem Failoverereignis auf einem Knoten geöffnet wurden, nach dem Failover auf dem neuen Knoten nicht verfügbar sind.)

In der vorherigen Liste sind nur einige Gründe für das Beenden von Verbindungen dargestellt. Weitere Informationen zu Verbindungsfehlern und Details zum Verwalten von Verbindungen in Windows Azure SQL-Datenbank finden Sie in den folgenden Dokumenten:

Optionen für die Verbindungsverwaltung im Code

Um die Verwaltung von Verbindungsproblemen in Windows Azure SQL-Datenbank zu erleichtern, stellt Microsoft folgende Funktionalität bereit:

  • Ein einheitlicher Ansatz bei der Angabe grundlegender Informationen, wie Servernamen und Sicherheitsanmeldeinformationen, bzw. vollständige Genauigkeit durch die Verwendung von Tools wie dem Massenkopierprogramm ("bpc.exe"). Beispiel: Ab SQL Server Native Client 11, JDBC, Version 4.0, und .NET Framework-Datenanbieter für SQL Server (System.Data.SqlClient) muss in .NET Framework, Version 4.0, beim Zugriff auf Windows Azure SQL-Datenbank nicht "username@server" angegeben werden.

  • Es wird sichergestellt, dass sämtliche Verbindungstechnologien eine Verbindung selbst dann aufrechterhalten können, wenn sie sich im Leerlauf befindet. Beispielsweise werden Erhaltungsintervalle für Datenbankverbindungen von der Java-Plattform im Gegensatz zu Windows nicht systemintern verwaltet. Daher sind bei JDBC-Komponenten, die eine Verbindung mit Windows Azure SQL-Datenbank herstellen, einige Änderungen an der Registrierungseinstellung erforderlich, um sicherzustellen, dass Verbindungen im Leerlauf nicht gelöscht werden.
    Weitere Informationen finden Sie im MSDN Library-Thema Herstellen einer Verbindung mit einer Windows Azure SQL-Datenbank.

Darüber hinaus hat Microsoft in den gängigen Datenzugriffsbibliotheken sowie in Windows Azure SQL-Datenbank Service Releases kontinuierlich Updates bereitgestellt. Das bedeutendste Update ist wahrscheinlich der Anwendungsblock zur Behandlung vorübergehender Fehler, eine Anwendungsbibliothek mit einer robusten Logik zur Behandlung vorübergehender Fehler. (Vorübergehende Fehler treten beispielsweise aufgrund einer temporären Bedingung auf, z. B. bei Netzwerkverbindungsproblemen oder einem nicht verfügbaren Dienst.) Der nächste Abschnitt bietet eine allgemeine Beschreibung dazu, wie der Anwendungsblock zur Behandlung vorübergehender Fehler auf eine Anwendung angewendet wird.

Kurzer Blick auf die Verwendung des Anwendungsblocks zur Behandlung vorübergehender Fehler

Der Anwendungsblock zur Behandlung vorübergehender Fehler kapselt Informationen zu vorübergehenden Fehlern, die bei Verwendung der folgenden Windows Azure-Dienste in der Anwendung auftreten können:

  • Windows Azure SQL-Datenbank

  • Windows Azure-Servicebus

  • Windows Azure-Speicher

  • Windows Azure Caching Service

In jedem dieser Dienste können andere vorübergehende Fehler auftreten. Aus diesem Grund verwendet der Anwendungsblock zur Behandlung vorübergehender Fehler für jeden Dienst spezifische Fehlererkennungsrichtlinien. Auf ähnliche Weise erfordern die verschiedenen Anwendungen unterschiedliche Strategien zur Fehlerbehandlung. Zur Berücksichtigung dieser Unterschiede bietet der Anwendungsblock zur Behandlung vorübergehender Fehler für die unterschiedlichen Szenarien für vorübergehende Fehler jeweils eine andere Wiederholungslogik. Diese Standardrichtlinien können durch die Erstellung benutzerdefinierter Klassen, die klar definierte Schnittstellen verfügbar machen, erweitert werden.

Die Verwendung des Anwendungsblocks zur Behandlung vorübergehender Fehler in vorhandenen Anwendungen hat kaum Auswirkungen. Der Anwendungsblock zur Behandlung vorübergehender Fehler verfügt entwurfsbedingt über mehrere Klassen und Erweiterungsmethoden, die das Verhalten einer typischen ADO.NET-Datenzugriffsebene imitieren.

Um die einfache Handhabung dieser Anwendungsbibliothek zu veranschaulichen, wird im Folgenden erläutert, wie der Anwendungsblock zur Behandlung vorübergehender Fehler auf vorhandenen Code angewendet wird. Im folgenden Beispiel wird eine einfache Methode veranschaulicht, durch die eine Datenbank abgefragt und das Resultset genutzt wird:

        public static void ReadFromDB()
        {

            using (SqlConnection conn = new SqlConnection(connString))
            {
                try
                {
                    conn.Open();

                    SqlCommand selectCommand = 
new SqlCommand(@"SELECT SOH.SalesOrderID
                         FROM SalesLT.SalesOrderHeader SOH 
                         JOIN SalesLT.SalesOrderDetail SOD ON SOH.SalesOrderID = SOD.SalesOrderID
                         JOIN SalesLT.Product P ON SOD.ProductID = P.ProductID
                         JOIN SalesLT.Customer C ON SOH.CustomerID = C.CustomerID
                         JOIN SalesLT.CustomerAddress CA on C.CustomerID = CA.CustomerID
                         JOIN SalesLT.Address A on CA.AddressID = A.AddressID
                         WHERE A.City=@City", conn);

                    selectCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Current, "London"));
                    selectCommand.CommandType = CommandType.Text;

                    IDataReader dataReader = selectCommand.ExecuteReader();

                    while (dataReader.Read())
                    {
                        Console.WriteLine("OrderID: {0}", dataReader["SalesOrderID"]);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: {0}",e.Message);
                }
            }

Um diesen Code stabiler zu gestalten, definieren Sie zuerst eine geeignete Wiederholungsstrategie. Zu diesem Zweck eignet sich am besten eine inkrementelle Wiederholungsstrategie. Zur Implementierung der Strategie verwenden Sie zunächst die Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure.SqlAzureTransientErrorDetectionStrategy-Klasse. Diese Klasse fängt Fehlercodes ab, die sich auf vorübergehende Fehlerbedingungen beziehen. Ersetzen Sie anschließend die System.Data.SqlClient SqlConnection-Klasse durch die Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure.ReliableSqlConnection-Klasse, wie im folgenden Codebeispiel gezeigt:

        public static void ReadFromDBWithReliableConnection()
        {

            // Define retry Strategy and Policy
            var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
            var retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);

            // Receive notifications about retries.
            retryPolicy.Retrying += new EventHandler<RetryingEventArgs>(retryPolicy_Retrying);

            using (ReliableSqlConnection conn = new ReliableSqlConnection(connString,retryPolicy))
            {
                try
                {
                    conn.Open();

                    SqlCommand selectCommand = new SqlCommand(@"SELECT SOH.SalesOrderID
                                        FROM SalesLT.SalesOrderHeader SOH 
                                        JOIN SalesLT.SalesOrderDetail SOD ON SOH.SalesOrderID = SOD.SalesOrderID
                                        JOIN SalesLT.Product P ON SOD.ProductID = P.ProductID
                                        JOIN SalesLT.Customer C ON SOH.CustomerID = C.CustomerID
                                        JOIN SalesLT.CustomerAddress CA on C.CustomerID = CA.CustomerID
                                        JOIN SalesLT.Address A on CA.AddressID = A.AddressID
                                        WHERE A.City=@City");

                    selectCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Current, "London"));
                    selectCommand.CommandType = CommandType.Text;

                    IDataReader dataReader = conn.ExecuteCommand<IDataReader>(selectCommand);

                    while (dataReader.Read())
                    {
                        Console.WriteLine("OrderID: {0}", dataReader["SalesOrderID"]);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: {0}", e.Message);
                }
            }
        
        }

Im vorherigen Codebeispiel wurde nicht nur eine geeignete Wiederholungslogik hinzugefügt, sondern auch der vorhandene SQLConnection-Code durch den ReliableSQLConnection-Code ersetzt. Eine Alternative, die neu zu schreibende Codemenge zu minimieren, besteht in der Verwendung der mit dem Anwendungsblock zur Behandlung vorübergehender Fehler bereitgestellten Erweiterungsmethoden. Dieser Ansatz reduziert nicht nur den Aufwand bei der Neuprogrammierung, sondern bietet ein allgemeines Verfahren zum Hinzufügen von Wiederholungsfunktionen zu einer ADO.NET-Anwendung. Um die Erweiterungsmethoden zu verwenden, ersetzen Sie die Open()-Methode und verschieden Execute-Methoden (z. B. ExecuteScalar(), ExecuteReader() oder ExecuteNonQuery()) durch ihre "Retry"-fähigen Entsprechungen, z. B. OpenWithRetry() oder ExecuteScalarWithRetry(). Dies wird im folgenden Codebeispiel veranschaulicht:

        public static void ReadFromDBWithExecute()
        {

            // Define retry Strategy and Policy
            var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
            var retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);

            // Receive notifications about retries.
            retryPolicy.Retrying += new EventHandler<RetryingEventArgs>(retryPolicy_Retrying);

            try
            {
                retryPolicy.ExecuteAction(
                  () =>
                  {
                      using (SqlConnection conn = new SqlConnection(connString))
                      {
                          conn.OpenWithRetry();

                          SqlCommand selectCommand = new SqlCommand(@"SELECT SOH.SalesOrderID
                                                FROM SalesLT.SalesOrderHeader SOH 
                                                JOIN SalesLT.SalesOrderDetail SOD ON SOH.SalesOrderID = SOD.SalesOrderID
                                                JOIN SalesLT.Product P ON SOD.ProductID = P.ProductID
                                                JOIN SalesLT.Customer C ON SOH.CustomerID = C.CustomerID
                                                JOIN SalesLT.CustomerAddress CA on C.CustomerID = CA.CustomerID
                                                JOIN SalesLT.Address A on CA.AddressID = A.AddressID
                                                WHERE A.City=@City",conn);

                          selectCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Current, "London"));
                          selectCommand.CommandType = CommandType.Text;

                          // Execute the above query using a retry-aware ExecuteCommand method which will
                          // automatically retry if the query has failed (or connection was dropped)
                          IDataReader dataReader = selectCommand.ExecuteReaderWithRetry(retryPolicy);
                          
                            while (dataReader.Read())
                            {
                                Console.WriteLine("OrderID: {0}", dataReader["SalesOrderID"]);
                            }                          
                      }
                  });
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: {0}", e.Message );
            }

        }

Der Anwendungsblock zur Behandlung vorübergehender Fehler unterstützt die Deklaration konfigurierbarer Wiederholungsrichtlinien. Weitere Informationen zum Deklarieren von Wiederholungsrichtlinien finden Sie unter Angeben von Wiederholungsstrategien in der Konfiguration.

Die hier aufgeführten Codebeispiele bieten einen kurzen Einblick in die Verwendung des Anwendungsblocks zur Behandlung vorübergehender Fehler. Ausführlichere Informationen zur Verwendung dieser Anwendungsbibliothek finden Sie im TechNet-Wiki-Lernprogramm: Wiederholungslogik für vorübergehende Fehler in Windows Azure SQL-Datenbanken.

Netzwerklatenz in Windows Azure SQL-Datenbank

Neben Verbindungsfehlern ist die Netzwerklatenz das zweite von aktuellen Windows Azure SQL-Datenbank-Benutzern meistgenannte Leistungsproblem.

Während die Auswirkungen der Internetlatenz bekannt sind, neigen Benutzer dazu, die Latenz zwischen der Anwendung und Windows Azure SQL-Datenbank zu unterschätzen. Selbst wenn Anwendung und Datenbanken im selben Datencenter gehostet werden, ist die Latenz in der Regel höher als in einer herkömmlichen lokalen Umgebung. Diese höhere Latenzzeit ist auf die Mehrinstanzenfähigkeit von Azure zurückzuführen. Außerdem verstärkt die höhere Latenz die Auswirkungen eines "geschwätzigen" Anwendungsverhaltens, da jeder Aufruf der Datenbank zusätzliche Latenz verursacht, die schließlich zu einer Beeinträchtigung der Gesamtleistung führen könnte. Folglich benötigen "geschwätzige" Anwendungen wesentlich mehr Zeit für den Zugriff auf eine in Windows Azure SQL-Datenbank gehostete Datenbank als für den auf eine lokal gehostete SQL Server-Datenbank.

Zusätzlich zur Latenz zwischen der Anwendung und Windows Azure SQL-Datenbank besteht eine erhöhte Latenz bei der Kommunikation zwischen den verschiedenen verteilten Komponenten Ihrer Lösung. Diese Art der Latenz macht möglicherweise den größten Unterschied zwischen lokalen und Cloudanwendungen aus. Die Latenz betrifft sowohl die Kommunikation zwischen Benutzer und Anwendung als auch die zwischen Anwendung und Windows Azure SQL-Datenbank.

Aus Sicht eines Endbenutzers entsprechen alle diese Ursachen für Netzwerklatenz der folgenden von einem Benutzer wahrgenommenen Antwortzeit:

Response Time = 2 x (Latency_1 + Latency_2) + Application_Processing_Time + Query_Exec_Time

Dabei entspricht

  • Latency_1 der Latenz zwischen dem Endbenutzer und dem Datencenter, in dem die Anwendung gehostet wird. (Diese Art der Latenz kann auch in lokalen Umgebungen vorkommen.)

  • Latency_2 der Latenz zwischen der Anwendung und den Datenbanken in Windows Azure SQL-Datenbank.

Um eine optimale Leistung zu gewährleisten, empfiehlt es sich, zunächst folgende grundlegende Aktionen auszuführen:

  • Minimieren Sie Latency_1, indem Sie ein Datencenter möglichst in der Nähe eines Großteils Ihrer Benutzer wählen.

  • Minimieren Sie Latency_2, indem Sie die Daten und die Windows Azure-Anwendung nah beieinander anordnen, um Netzwerkroundtrips zu verringern.

  • Minimieren Sie Application_Processing_Time und Query_Exec_Time, indem Sie die allgemeinen Best Practices verwenden, die Sie bei lokalen Datenbanken befolgen würden, wenn Sie auf die Datenschicht zugreifen, Leistungsaspekte behandeln und den Code optimieren.

Minimieren der Entfernung zwischen Daten und Anwendungen

Es ist wichtig, dass die Anwendung so nah wie möglich an den gehosteten Datenbanken ausgeführt wird. Wenn die Anwendung im Datencenter "North Central US" ausgeführt und die Datenbank im Datencenter "North Central US" gehostet wird, erzielen Sie den kürzesten Roundtrip und somit die kürzeste entfernungsbedingte Latenz.

Obwohl es möglich ist, von einer lokal gehosteten Anwendung auf eine in Windows Azure gehostete Datenbank zuzugreifen, sollten Sie bedenken, dass dadurch nicht nur eine höhere Latenz beim Datenzugriff, sondern auch Gebühren für den Datentransfer aus dem Datencenter entstehen.

Falls der Zugriff auf Daten an unterschiedlichen geografischen Standorten erforderlich ist, sollten Sie statische Daten über das Netzwerk für die Inhaltsübermittlung auf mehrere Standorte verteilen. Alternativ erstellen Sie mehrere Kopien einer Datenbank in verschiedenen Datencentern und synchronisieren die Daten standortübergreifend mit SQL-Datensynchronisierung (Vorschau). Diese Ansätze unterstützen Anwendungen, die an unterschiedlichen geografischen Standorten ausgeführt werden, da sich die Daten in größerer Nähe zu den verschiedenen Anwendungsinstanzen befinden und die Gesamtlatenz reduziert wird.

noteHinweis
SQL-Datensynchronisierung (Vorschau) wird derzeit nur als Vorschau zur Verfügung gestellt, um Produktfeedback für zukünftige Versionen zu sammeln. Sie sollte nicht in Produktionsumgebungen eingesetzt werden.

Minimieren von Netzwerkroundtrips

Die Eindämmung von Netzwerkroundtrips ist zwar auch für lokale Anwendungen wichtig, hat in Windows Azure jedoch eine größere Bedeutung. Von Windows Azure SQL-Datenbank verarbeitete Abfragen müssen Netzwerklastenausgleichsschichten sowie das TDS-Protokollgateway passieren, bevor sie von Windows Azure SQL-Datenbank empfangen werden. Während die Windows Azure SQL-Datenbank dem Endbenutzer dank dieser Abstraktion Skalierungsmöglichkeiten und Verfügbarkeit bieten kann, erfordert sie andererseits eine bestimmte Verarbeitungsleistung, die bei jedem Roundtrip eine geringe Latenz verursacht. Bei Anwendungen, die Daten in vielen sequenziellen Roundtrips an Windows Azure SQL-Datenbank senden, kann eine erhebliche Leistungsverschlechterung auftreten.

Um die Effekte von Roundtrips zu minimieren, befolgen Sie dieselben Best Practices wie bei lokalen Anwendungen:

  • Verwenden Sie gespeicherte Prozeduren, insbesondere zum Kapseln komplexer Datenzugriffslogik sowie von Transaktionsverhalten: Beim Ausführen sequenzieller Aufrufe, bei denen der zweite Aufruf von Daten abhängig ist, die vom ersten zurückgegeben werden, wird durch die Verwendung einer gespeicherten Prozedur zum Ausführen der Logik für den zweiten Aufruf mindestens ein Roundtrip eingespart und die Leistung beschleunigt. Durch diesen Ansatz werden Roundtrips, Ressourcensperren sowie die Ressourcennutzung auf Serverseite naturgemäß verringert.

  • Minimieren Sie die Cursorverwendung oder zeilenweise Zugriffe: Verwenden Sie möglichst setbasierte Vorgänge. Falls nicht auf Cursor verzichtet werden kann, verwenden Sie einen clientseitigen Cursor.

  • Verwenden Sie Tabellenwertparameter, um in jedem Roundtrip mehrere Zeilen an Windows Azure SQL-Datenbank zu senden: Windows Azure SQL-Datenbank verwendet genauso wie lokale Versionen des SQL Server-Datenbankmoduls Tabellenwertfunktionen. Mithilfe von Tabellenwertparametern können mehrere Aufrufe derselben gespeicherten Prozedur, mit der ein Satz von Datensätzen/Werten verarbeitet werden soll, reduziert werden. Sie können auch tabellarische Parameter an eine einzelne parametrisierte Abfrage übergeben, z. B. einen der Befehle SELECT, INSERT, UPDATE oder DELETE.
    Weitere Informationen finden Sie im folgenden Thema der Onlinedokumentation: Verwenden von Tabellenwertparametern.

  • Verwenden Sie möglichst lokales Caching: Mit dem lokalen Caching können dieselben Ergebnisse wiederverwendet werden, ohne dass mehrere Roundtrips zu Windows Azure SQL-Datenbank erforderlich sind. Bedenken Sie auch, dass Sie Aufrufe gespeicherter Prozeduren zwischenspeichern können, die denselben Wert zurückgeben, wenn derselbe angegeben wird.

  • Verwenden Sie möglichst Windows Azure Caching: Verwenden Sie Windows Azure Caching für schreibgeschützte Suchdaten, um den Netzwerkdatenverkehr mit Windows Azure SQL-Datenbank zu minimieren. Weitere Informationen finden Sie unter Reduzieren von Netzwerkroundtrips mit Windows Azure Caching.

  • Metadaten und Daten sollten möglichst zwischengespeichert werden.

  • Vermeiden Sie den Abruf von Metadaten zur Laufzeit, falls möglich.

  • Vermeiden Sie die Verwendung von Klassen wie "SqlCommandBuilder": Durch diese Klassen werden Metadaten zur Laufzeit abgefragt und zusätzliche Roundtrips verursacht.

  • Fassen Sie SQL-Anweisungen möglichst in Batches zusammen: Sie können mehrere Transact-SQL-Anweisungen in einem einzelnen Batchbefehl verketten, um mehrere Resultsets abzurufen oder mehrere DML-Vorgänge in einem einzelnen Netzwerkroundtrip auszuführen. Dieser Ansatz trifft insbesondere dann zu, wenn zahlreiche aufeinander folgenden INSERT-Vorgänge verarbeitet werden.

  • Vermeiden Sie die anwendungsbasierte Transaktionsverwaltung: Das Kapseln von Transaktionsverwaltungsvorgängen, wie BEGIN TRAN, COMMIT/ROLLBACK, in gespeicherte Prozeduren kann Netzwerkroundtrips und Sperren reduzieren.

Befolgen allgemeiner Best Practices für lokale Datenbanken

Nachdem Sie die Entfernung zwischen Daten und Benutzern verringert sowie Netzwerkroundtrips minimiert haben, muss im nächsten Schritt sichergestellt werden, dass die Anwendung den allgemeinen Best Practices für lokale Datenbanken entspricht. Nachdem bekannte Best Practices und Empfehlungen auf die Datenzugriffsebene der Anwendung angewendet und mit weiteren Best Practices zur Leistung und Optimierung kombiniert wurden, sollte in einer Umgebung mit hoher Latenz wie der Cloud ein mehrfacher Nutzeneffekt zu verzeichnen sein.

Die allgemeinen Best Practices für Datenbankinteraktionen mit lokalen Datenbanken umfassen folgende Empfehlungen:

  • Eine Verbindung sollte so spät wie möglich geöffnet und so früh wie möglich geschlossen werden: Um sowohl die Ressourcennutzung als auch eine mögliche Einschränkung zu minimieren, öffnen Sie in der Anwendung eine Verbindung erst an dem Punkt, an dem sie für den Code erforderlich wird. Darüber hinaus sollte die Verbindung sofort an den Pool zurückgegeben werden, nachdem sie im Code durch Verwerfen des Verbindungsobjekts beendet wurde. (Eine Ausnahme von dieser Rückgaberichtlinie besteht dann, wenn direkt weitere Daten verarbeitet werden müssen. In diesem Fall sollte die Verbindung erst nach Abschluss der unmittelbaren Verarbeitung zurückgegeben werden.)

  • Nutzen Sie Verbindungspools: Auf Prozessebene enthalten Verbindungspools Verbindungen, die dieselbe Datenbank zum Ziel haben und den gleichen Sicherheitskontext verwenden. Verwenden Sie möglichst dieselbe Verbindungszeichenfolge für alle Verbindungen, die die gleichen Merkmale aufweisen.

  • Rufen Sie nur die Daten ab, die Sie benötigen: Gehen Sie bei der Definition der SELECT-Liste und WHERE-Klausel mit Sorgfalt vor. Dieser Ansatz ermöglicht es Ihnen, die verwendete Netzwerkbandbreite zu minimieren und die Datenbank für eine optimale Leistung zu indizieren.

  • Halten Sie Transaktionen so kurz wie möglich, und verwenden Sie keine unnötigen Ressourcen: Ein suboptimaler Datenmodellentwurf und übermäßige Roundtrips zwischen dem Anwendungscode und den Datenbanken stellen häufige Probleme dar, sind in lokalen Bereitstellungen aber nicht als kritisch anzusehen, weil die Umgebung Verbindungen mit geringer Latenz aufweist. Außerdem können diese Anwendungen aus folgenden Gründen häufig nicht so einfach geändert werden:

    • Vorhandene Einschränkungen der Architektur.

    • Datenzugriff und Geschäftslogik sind aufgrund eines monolithischen Entwurfs eng verbunden und voneinander abhängig.

    • Einige Aspekte, z. B. die zeilenweise Datenverarbeitung, die für die Anwendungslogik selbst erforderlich sind, und ohne eine erhebliche Umprogrammierung nicht zu ändern sind.

Neben diesen allgemeinen Best Practices gibt es weitere Best Practices, die sich auf die in der Anwendung verwendeten Technologien beziehen. Beispielsweise sind Anwendungen, die .NET Framework nutzen, in der Lage, Technologien wie ADO.NET, Entity Framework und WCF Data Services zu verwenden. Dieses Technologien bieten kürzere Entwicklungszeiten und eine höhere Flexibilität bei der Implementierung der Datenzugriffsebene für beliebige Anwendungsformate. Außerdem eignen sich die Technologien für serviceorientierte Umgebungen, da Ebenen entkoppelt, Schemaflexibilität ermöglicht, offene Datenarchitekturen (z. B. OData) verwendet werden und ein immanenter "getrennter" Entwurf unterstützt wird. Trotz der Vorteile können die Technologien jedoch dieselben Probleme verursachen, die auch für ältere Anwendungen genannt wurden, z. B. "Chattiness", wenn Sie keinen geeigneten Datenentwurf sowie eine entsprechende Vorgangsoptimierung vorsehen (dazu gehören optimale Datendarstellung, Cachenutzung und das Zusammenfassen datenbezogener Vorgänge in Batches, um unnötige Roundtrips zu reduzieren).

In den folgenden Abschnitten werden einige Best Practices für diese Technologien sowie für die asynchrone Programmierung für Azure-Anwendungen beschrieben.

Best Practices für ODBC und JDBC

Bei Datenzugriffsbibliotheken, z. B. ODBC und JDBC, in denen die clientseitige Unterstützung intelligenter Vorgänge (z. B. Sortieren, Filtern usw.) begrenzt ist, können Sie trotzdem vorhandene Optimierungstechniken anwenden, wie das Verringern cursorbasierter Vorgänge und der zeilenweisen Verarbeitung. Wenn Cursor erforderlich sind, verwenden Sie schreibgeschützte Vorwärtscursor zum Abrufen von Werten, und SQL-Befehle für Datenänderungen, anstatt positionierte Updates in Cursorn auszuführen.

Best Practices für ADO.NET

In ADO.NET können mehrere Optimierungen angewendet werden, um die Effizienz des Datenzugriffscodes zu maximieren:

  • Wählen Sie den geeigneten Ausführungsmodus mit SqlCommand. Wenn Sie z. B. nur einen Skalarwert abrufen müssen, verwenden Sie die ExecuteScalar()-Methode bzw. ExecuteNonQuery()-Methode, wenn Sie kein Resultset abrufen müssen.

  • Verwenden Sie die UpdateBatchSize-Eigenschaft, wenn Sie mehrere Vorgänge mithilfe der SqlDataAdapter-Klasse ausführen: Dadurch werden mehrere Befehle in einem Batch im Netzwerk übertragen und Netzwerkroundtrips minimiert.

  • Verwenden Sie SqlDataAdapter zur Implementierung direkter Datenbankinteraktionen, indem Sie gespeicherte Prozeduren für SELECT-, INSERT-, UPDATE- und DELETE-Vorgänge einsetzen.

  • Legen Sie bei Verwendung von Datasets als clientseitigen Cache die SerializationFormat-Eigenschaft auf "Binary" fest: Dadurch wird die übertragene Datenmenge reduziert.

Best Practices für Entity Framework

Im Bereich der Datenzugriffsentwicklung bietet Entity Framework zahlreiche interessante Aspekte, die nachfolgend erläutert werden:

  • Entity Framework bietet eine leistungsstarke ORM-Umgebung (Object-Relational Mapping), mit der die Entwicklungszeit erheblich verkürzt werden kann.

  • Die Flexibilität wird größer, da die physische Datenbankschemadefinition von der konzeptionellen Darstellung der Anwendungsdaten entkoppelt wird.

  • Es steht eine vollständige Reihe von Diensten zur Unterstützung der Persistenz zur Verfügung.

  • Netzwerkroundtrips werden reduziert, da Resultsets aus Windows Azure SQL-Datenbank in Objektsätze im Anwendungsspeicher geladen und ohne bestehende Verbindung wiederverwendet werden können, ohne dass für jeden Vorgang eine Interaktion mit dem Back-End erforderlich ist.

Wie jedes andere Programmiertool kann Entity Framework jedoch Leistungsprobleme verursachen, sodass die Verarbeitung von Datenbankinteraktionen besondere Aufmerksamkeit erfordert. Durch die Windows Azure-Umgebung werden diese Leistungsbelange noch verstärkt.

Um das Zusammenwirken von Entity Framework und Windows Azure SQL-Datenbank zu optimieren, befolgen Sie diese Best Practices:

  • Deaktivieren Sie explizit die Nachverfolgung des Objektstatus auf ObjectStateManager-Ebene sowohl für Entitäten als auch für Beziehungen: Wenden Sie diese Richtlinie an, wenn der Objektstatus aufgrund einer typischen schreibgeschützten Verwendung von der Anwendung nicht nachverfolgt werden muss.

  • Deaktivieren Sie Lazy Loading, um die Interaktion zwischen Code und Datenbank besser zu steuern: Um Roundtrips zu reduzieren, würden Sie alle erforderlichen Daten in einer einzelnen Interaktion vorab laden. Sie können mehrere Befehle sowohl beim Laden als auch beim persistenten Speichern von Daten im Datenspeicher in einem Batch zusammenfassen, indem Sie den Objektkontext mit spezifischen Methoden erweitern.

  • Verwenden Sie möglichst gespeicherte Prozeduren für Interaktionen mit dem Datenspeicher: Wenn keine gespeicherten Prozeduren verwendet werden können, nutzen Sie parametrisierte Abfragen und indizierte Sichten zur Leistungsverbesserung.

  • Führen Sie mehrere Datenbankvorgänge in einem einzelnen Roundtrip aus, indem Sie Tabellenwertparameter integrieren und Objektsätze tabellarischen Parametern von gespeicherten Prozeduren zuordnen: Dieser Ansatz kann selbst dann verwendet werden, wenn er von den Entwurfstools nicht direkt unterstützt wird.

  • Ordnen Sie mehrere Resultsets Objekten möglichst in einem einzelnen Vorgang zu.

  • Ordnen Sie Objektsätze beim Einfügen sehr großer Datenmengen der System.Data.SqlClient.SqlBulkCopy.WriteToServer()-Methode zu: Mithilfe der SQLBulkCopy-Methode können das SQL Server-Datenbankmodul und Windows Azure SQL-Datenbank Optimierungen für die Protokollierung von Massenvorgängen nutzen, durch die umfangreiche Einfügevorgänge häufig schneller ausgeführt werden können.

Weitere Informationen finden Sie unter Verringern der Netzwerklatenz für Windows Azure SQL-Datenbanken mithilfe von Entity Framework.

Best Practices für die asynchrone Programmierung

Die Ausführung einiger Datenbankvorgänge, z. B. Befehlsausführungen, kann extrem lange dauern. In derartigen Fällen müssen Singlethread-Anwendungen andere Vorgänge blockieren und warten, bis der Befehl abgeschlossen ist, bevor die anderen Vorgänge fortgesetzt werden. Im Gegensatz dazu kann der Vordergrundthread während des gesamten Vorgangs aktiv bleiben, wenn der Vorgang mit langer Ausführungszeit einem Hintergrundthread zugewiesen wird.

ADO.NET unterstützt dieselben Entwurfsmuster in der SqlCommand-Klasse. Die asynchrone Unterstützung wird insbesondere durch die jeweilige Kombination der Methoden BeginExecuteNonQuery(), BeginExecuteReader() und BeginExecuteXmlReader() mit den Methoden EndExecuteNonQuery(), EndExecuteReader() und EndExecuteXmlReader() ermöglicht.

Diese asynchronen Methoden entbinden Sie jedoch nicht davon, alle in den vorherigen Abschnitten erwähnten Optimierungen und Best Practices anzuwenden. Die asynchronen Methoden helfen jedoch, die Auswirkungen von Datenbankvorgängen mit langer Ausführungszeit in der Datenzugriffsebene zu reduzieren, indem sie die Möglichkeit bieten, andere Vorgänge parallel mit der Abfrage in Windows Azure SQL-Datenbank auszuführen.

Community-Beiträge

HINZUFÜGEN
Anzeigen:
© 2014 Microsoft