Profilowanie danych wydajności sterownika ODBC

Dotyczy:sql ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

Ten przykładowy przykład pokazuje specyficzne dla sterownika SQL Server opcje rejestrowania statystyk wydajności. Próbka tworzy jeden plik: odbcperf.log. Ten przykład pokazuje zarówno tworzenie pliku logu wydajności, jak i wyświetlanie danych wydajności bezpośrednio ze struktury danych SQLPERF (struktura SQLPERF jest zdefiniowana w Odbcss.h.). Ten próbka została opracowana dla wersji ODBC 3.0 lub nowzej.

Ważna

Jeśli to możliwe, użyj uwierzytelniania systemu Windows. Jeśli uwierzytelnianie Windows nie jest dostępne, poprosz użytkowników o wpisanie danych uwierzytelniających w czasie działania. Unikaj przechowywania danych uwierzytelniających w plikach. Jeśli musisz utrzymywać dane uwierzytelniające, powinieneś je zaszyfrować za pomocą API kryptograficznego Win32.

Aby rejestrować dane wydajności sterowników za pomocą ODBC Administrator

  1. W Panel sterowania kliknij dwukrotnie Narzędzia administracyjne, a następnie Źródła danych (ODBC). Alternatywnie możesz wywołać odbcad32.exe.

  2. Kliknij zakładkę User DSN, System DSN lub File DSN .

  3. Kliknij źródło danych, dla którego chcesz zarejestrować wydajność.

  4. Kliknij przycisk Konfiguruj.

  5. W kreatorze konfiguracji DSN Microsoft SQL Server przejdź do strony ze statystykami sterownika Log ODBC do pliku logu.

  6. Wybierz Log statystyki sterownika ODBC do pliku logu. W polu umieść nazwę pliku, w którym statystyki powinny być zapisane. Opcjonalnie kliknij Przeglądaj , aby przejrzeć system plików z dziennikiem statystyk.

Programowanie rejestrowania danych o wydajności sterownika

  1. Zadzwoń do SQLSetConnectAttr z SQL_COPT_SS_PERF_DATA_LOG oraz pełną ścieżką i nazwą pliku loga wydajności. Przykład:

    "C:\\Odbcperf.log"  
    
  2. Zadzwoń do SQLSetConnectAttr z SQL_COPT_SS_PERF_DATA i SQL_PERF_START, aby rozpocząć logowanie danych wydajności.

  3. Opcjonalnie wywołaj SQLSetConnectAttr z SQL_COPT_SS_LOG_NOW i NULL, aby zapisać rekord danych wydajności rozdzielony tabulatorami do pliku dziennika wydajności. Można to robić wielokrotnie w trakcie działania aplikacji.

  4. Zadzwoń do SQLSetConnectAttr z SQL_COPT_SS_PERF_DATA i SQL_PERF_STOP, aby przestać rejestrować dane o wydajności.

Pobieranie danych o wydajności sterownika do aplikacji

  1. Zadzwoń do SQLSetConnectAttr z SQL_COPT_SS_PERF_DATA i SQL_PERF_START, aby rozpocząć profilowanie danych wydajności.

  2. Zadzwoń do SQLGetConnectAttr z SQL_COPT_SS_PERF_DATA i adresem wskaźnika do struktury SQLPERF. Pierwsze takie wywołanie ustawia wskaźnik na adres ważnej struktury SQLPERF, która zawiera aktualne dane wydajności. Sterownik nie odświeża danych w strukturze wydajności na bieżąco. Aplikacja musi powtarzać wywołanie do SQLGetConnectAttr za każdym razem, gdy musi odświeżyć strukturę z nowszymi danymi wydajnościowymi.

  3. Zadzwoń do SQLSetConnectAttr z SQL_COPT_SS_PERF_DATA i SQL_PERF_STOP, aby przestać rejestrować dane o wydajności.

Example

Będziesz potrzebować źródła danych ODBC o nazwie AdventureWorks, którego domyślną bazą danych jest przykładowa baza danych AdventureWorks. (Możesz pobrać przykładową bazę danych AdventureWorks z repozytorium Azure Data SQL Samples Repository GitHub.) To źródło danych musi opierać się na sterowniku ODBC dostarczonym przez system operacyjny (nazwa sterownika to "SQL Server"). Jeśli chcesz zbudować i uruchomić ten przykład jako aplikację 32-bitową na 64-bitowym systemie operacyjnym, musisz utworzyć źródło danych ODBC za pomocą administratora ODBC w %windir%\SysWOW64\odbcad32.exe.

Ten przykład łączy się z domyślną instancją SQL Server na Twoim komputerze. Aby połączyć się z nazwaną instancją, zmień definicję źródła danych ODBC, aby określić instancję w następującym formacie: serwer\namedinstance. Domyślnie SQL Server Express instaluje się na nazwanej instancji.

Kompiluj za pomocą odbc32.lib.

// compile with: odbc32.lib  
#include <stdio.h>  
#include <string.h>  
#include <windows.h>  
#include <sql.h>  
#include <sqlext.h>  
#include <odbcss.h>  
  
SQLHENV henv = SQL_NULL_HENV;  
SQLHDBC hdbc1 = SQL_NULL_HDBC;       
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;  
  
void Cleanup() {  
   if (hstmt1 != SQL_NULL_HSTMT)  
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);  
  
   if (hdbc1 != SQL_NULL_HDBC) {  
      SQLDisconnect(hdbc1);  
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);  
   }  
  
   if (henv != SQL_NULL_HENV)  
      SQLFreeHandle(SQL_HANDLE_ENV, henv);  
}  
  
int main() {  
   RETCODE retcode;  
  
   // Pointer to the ODBC driver performance structure.  
   SQLPERF *PerfPtr;  
   SQLINTEGER cbPerfPtr;  
  
   // Allocate the ODBC environment and save handle.  
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);  
   if( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLAllocHandle(Env) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Notify ODBC that this is an ODBC 3.0 app.  
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);  
   if( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");  
      Cleanup();  
      return(9);      
   }  
  
   // Allocate ODBC connection handle and connect.  
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);  
   if( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {  
      printf("SQLAllocHandle(hdbc1) Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // This sample use Integrated Security. Please create the SQL Server   
   // DSN by using the Windows NT authentication.   
   retcode = SQLConnect(hdbc1, (UCHAR*)"AdventureWorks", SQL_NTS, (UCHAR*)"", SQL_NTS, (UCHAR*)"", SQL_NTS);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLConnect() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Set options to log performance statistics.  Specify file to use for the log.  
   retcode = SQLSetConnectAttr( hdbc1, SQL_COPT_SS_PERF_DATA_LOG, &"odbcperf.log", SQL_NTS);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLSetConnectAttr() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Start the performance statistics log.  
   retcode =   
      SQLSetConnectAttr( hdbc1, SQL_COPT_SS_PERF_DATA, (SQLPOINTER)SQL_PERF_START, SQL_IS_UINTEGER);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLSetConnectAttr() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Allocate statement handle, then execute command.  
   retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLAllocHandle() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"SELECT * FROM Purchasing.Vendor", SQL_NTS);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clear any result sets generated.  
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA ) {  
      if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
         printf("SQLMoreResults() Failed\n\n");  
         Cleanup();  
         return(9);  
      }  
   }  
  
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"SELECT * FROM Sales.Store", SQL_NTS);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clear any result sets generated.  
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA ) {  
      if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
         printf("SQLMoreResults() Failed\n\n");  
         Cleanup();  
         return(9);  
      }  
   }  
  
   // Generate a long-running query.  
   retcode = SQLExecDirect(hstmt1, (UCHAR*)"waitfor delay '00:00:04' ", SQL_NTS);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLExecDirect() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Clear any result sets generated.  
   while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA ) {  
      if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
         printf("SQLMoreResults() Failed\n\n");  
         Cleanup();  
         return(9);  
      }  
   }  
  
   // Write current statistics to the performance log.  
   retcode =   
      SQLSetConnectAttr( hdbc1, SQL_COPT_SS_PERF_DATA_LOG_NOW, (SQLPOINTER)NULL, SQL_IS_UINTEGER);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLSetConnectAttr() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   // Get pointer to current SQLPerf structure.  
   // Print a couple of statistics.  
   retcode =   
      SQLGetConnectAttr( hdbc1, SQL_COPT_SS_PERF_DATA, (SQLPOINTER)&PerfPtr, SQL_IS_POINTER, &cbPerfPtr);  
   if( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {  
      printf("SQLGetConnectAttr() Failed\n\n");  
      Cleanup();  
      return(9);  
   }  
  
   printf("SQLSelects = %d, SQLSelectRows = %d\n", PerfPtr->SQLSelects, PerfPtr->SQLSelectRows);  
  
   // Cleanup  
   SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);  
   SQLDisconnect(hdbc1);  
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);  
   SQLFreeHandle(SQL_HANDLE_ENV, henv);  
}