Adatbázisfigyelő monitorozási adatainak elemzése (előzetes verzió)

A következőkre vonatkozik:Azure SQL DatabaseFelügyelt Azure SQL-példány

Amellett, hogy irányítópultokat használ az Azure Portalon, vagy vizualizációkat készít az SQL monitorozási adatainak megtekintéséhez és elemzéséhez Power BI, Grafana, Azure Data Explorer vagy Real-Time Analytics a Microsoft Fabric-ben, közvetlenül lekérdezheti a monitorozási adattárat.

Ez a cikk példákat tartalmaz KQL- és T-SQL- lekérdezésekre, amelyek segítenek az összegyűjtött monitorozási adatok elemzésének megkezdésében.

A KQL használata a monitorozási adatok elemzéséhez

Az összegyűjtött monitorozási adatok elemzéséhez ajánlott a Kusto Query Language (KQL) használata. A KQL optimális a telemetriai adatok, metrikák és naplók lekérdezéséhez. Széles körű támogatást nyújt a szöveges kereséshez és elemzéshez, az idősorozat-operátorokhoz és -függvényekhez, az elemzéshez és az összesítéshez, valamint számos más olyan nyelvi szerkezethez, amely elősegíti az adatelemzést.

A KQL fogalmilag hasonló az SQL-hez. Sémaentitásokon, például táblákon és oszlopokon működik, és támogatja az SQL SELECT, JOIN, WHEREés GROUP BY záradékainak megfelelő relációs műveleteket, például a projektet, a korlátozást, a csatlakozást és az összegzést.

KQL-lekérdezések írásához és végrehajtásához használhatja Kusto Explorer vagy a Azure Data Explorerwebes felhasználói felületi. A Kusto Explorer egy teljes funkcionalitású Windows asztali szoftver, míg az Azure Data Explorer webes felhasználói felülete lehetővé teszi KQL-lekérdezések végrehajtását és az eredmények megjelenítését a böngészőben bármilyen platformon.

Ezekkel az eszközökkel adatbázist is lekérdezhet a Microsoft Fabric Real-Time Analytics szolgáltatásában. A csatlakozáshoz adjon hozzá egy új kapcsolatot a lekérdezési URI a Real-Time Analytics-adatbázis használatával. Emellett, ha a Real-Time Analytics szolgáltatást használja, a monitorozási adatokat elemezheti a KQL-lekérdezéskészletek segítségével. A KQL-lekérdezéskészlet menthető megosztható hálóösszetevőként, és Power BI-jelentések létrehozásához használható.

Ha még nem kezdte el a KQL-t, az alábbi erőforrások segíthetnek az első lépésekben:

Az alábbi példák segíthetnek saját KQL-lekérdezések írásában az összegyűjtött SQL monitorozási adatok megtekintéséhez és elemzéséhez. Ezeket a példákat kiindulási pontként is használhatja saját adatvizualizációk és irányítópultok készítéséhez.

Erőforrás-felhasználás lekérdezése a KQL használatával az idő függvényében

Ebben a példában a lekérdezés erőforrás-használati metrikákat (CPU, feldolgozók, naplóírási teljesítmény stb.) ad vissza egy adatbázis, egy rugalmas készlet vagy egy felügyelt SQL-példány elsődleges replikájához az elmúlt egy órában. Az eredményhalmaz visszaadása mellett idődiagramként jeleníti meg.

Ebben és más példákban módosítsa a változókat a utasításokban úgy, hogy azok megfeleljenek a kiszolgáló, az adatbázis, a rugalmas készlet vagy a felügyelt SQL-példány nevének. Ha másik időintervallumot szeretne használni, módosítsa a duration változót. További információ: időbélyegek.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let logicalServer = @"your-server-name";
let databaseName = @"your-database-name";
let replicaType = "Primary";
let duration = 1h;
sqldb_database_resource_utilization
| where sample_time_utc > ago(duration)
| where logical_server_name =~ logicalServer
| where database_name =~ databaseName
| where replica_type =~ replicaType
| project sample_time_utc,
          avg_cpu_percent,
          avg_instance_cpu_percent,
          avg_data_io_percent,
          avg_log_write_percent,
          max_worker_percent
| sort by sample_time_utc desc
| render timechart;

A KQL használata az adatbázis, a rugalmas készlet vagy a felügyelt SQL-példány tulajdonságainak megtekintéséhez

Ebben a példában a lekérdezés visszaadja az összes adatbázist, rugalmas csomagot vagy SQL-felügyelt példányt, amelyből az elmúlt egy napban legalább egy mintát gyűjtöttek a megfelelő Tulajdonságokadathalmaz-ban. Más szóval minden sor egy monitorozási célt jelöl a legutóbb megfigyelt tulajdonságokkal.

A arg_max() függvény összesíti az adatokat a célokat azonosító megadott oszlopkészlet legújabb sorának visszaadásához. Azure SQL-adatbázisok esetében például ez a készlet logical_server_name, database_name, replica_type.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let duration = 1d;
sqldb_database_properties
| where sample_time_utc > ago(duration)
| summarize arg_max(sample_time_utc, *) by logical_server_name, database_name, replica_type
| project-rename last_sample_time_utc = sample_time_utc
| sort by tolower(logical_server_name) asc,
          tolower(database_name) asc,
          case(
              replica_type == "Primary", 0,
              replica_type == "Geo-replication forwarder", 1,
              replica_type == "Named secondary", 2,
              replica_type == "HA secondary", 3,
              4) asc;

A KQL használata a lekérdezési futtatókörnyezet statisztikáinak megtekintéséhez

Ez a lekérdezés az Azure SQL-tulajdonban lévő legtöbb erőforrást használó lekérdezést adja vissza. Módosítsa a változót a lekérdezések rangsorolására bármely Lekérdezéstár metrika alapján, beleértve a processzoridőt, az eltelt időt, a végrehajtás számát stb. A változókat úgy is beállíthatja, hogy időintervallum, lekérdezésvégrehajtási típus és lekérdezésszöveg szerint szűrjenek. Állítsa be a változókat, hogy egy adott logikai kiszolgálóra, rugalmas készletre, felügyelt SQL-példányra vagy adatbázisra összpontosítsanak.

A lekérdezés a Lekérdezés futtatókörnyezeti statisztikáitadatkészletet használja a megadott leggyakoribb lekérdezések számának visszaadásához, és tartalmazza azok rangsorolását minden más erőforrás-felhasználási metrika alapján.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let topQueriesBy = "cpu_time"; // Set to one of the following metrics to return the top resource consuming queries:
// count_executions, duration, cpu_time, logical_io_reads, logical_io_writes, physical_io_reads, 
// num_physical_io_reads, clr_time, dop, query_max_used_memory, rowcount, log_bytes_used, tempdb_space_used 
let topQueries = 10; // Set the number of top queries to return
let endTime = now();
let startTime = endTime - 1d;
let logicalServerName = @""; // Optionally filter by logical server name
let elasticPoolName = @""; // Optionally filter by elastic pool name, if any databases are in elastic pools
let databaseName = @""; // Optionally filter by database name
let executionType = ""; // Optionally filter by execution type. Use Regular, Aborted, Exception.
let queryHash = ""; // Optionally filter by query hash (example: 0xBAAA461A6C93EA88)
let queryTextFragment = ""; // Optionally filter by a query text fragment
sqldb_database_query_runtime_stats
| where interval_start_time >= startTime and interval_end_time <= endTime
| where isempty(executionType) or execution_type_desc =~ executionType
| where isempty(logicalServerName) or logical_server_name =~ logicalServerName
| where isempty(elasticPoolName) or elastic_pool_name =~ elasticPoolName
| where isempty(databaseName) or database_name =~ databaseName
| summarize dcount_logical_servers = dcount(logical_server_name),
            any_logical_server_name = take_any(logical_server_name),
            dcount_elastic_pools = dcount(strcat(logical_server_name, "|", elastic_pool_name)),
            any_elastic_pool_name = take_any(elastic_pool_name),
            dcount_databases = dcount(strcat(logical_server_name, "|", database_name)),
            any_database_name = take_any(database_name),
            dcount_sql_module_name = dcount(sql_module_name),
            any_sql_module_name = take_any(sql_module_name),
            dcount_context_settings_id = dcount(context_settings_id),
            any_context_settings_id = take_any(context_settings_id),
            query_sql_text = take_any(query_sql_text),
            count_executions = sum(toreal(count_executions)),
            count_successful_executions = sumif(toreal(count_executions), execution_type_desc == "Regular"),
            count_aborted_executions = sumif(toreal(count_executions), execution_type_desc == "Aborted"),
            count_exception_executions = sumif(toreal(count_executions), execution_type_desc == "Exception"),
            duration_us = sum(avg_duration_us * count_executions),
            cpu_time_us = sum(avg_cpu_time_us * count_executions),
            logical_io_reads = sum(avg_logical_io_reads * count_executions),
            logical_io_writes = sum(avg_logical_io_writes * count_executions),
            physical_io_reads = sum(avg_physical_io_reads * count_executions),
            num_physical_io_reads = sum(avg_num_physical_io_reads * count_executions),
            clr_time_us = sum(avg_clr_time_us * count_executions),
            dop = sumif(avg_dop * count_executions, is_parallel_plan),
            query_max_used_memory = sum(avg_query_max_used_memory * count_executions),
            rowcount = sum(avg_rowcount * count_executions),
            log_bytes_used = sum(avg_log_bytes_used * count_executions),
            tempdb_space_used = sum(avg_tempdb_space_used * count_executions)
            by query_hash
| project logical_server_name = iif(dcount_logical_servers == 1, any_logical_server_name, strcat(any_logical_server_name, " (+", tostring(dcount_logical_servers - 1), ")")),
          elastic_pool_name = iif(dcount_elastic_pools == 1, any_elastic_pool_name, strcat(any_elastic_pool_name, " (+", tostring(dcount_elastic_pools - 1), ")")),
          database_name = iif(dcount_databases == 1, any_database_name, strcat(any_database_name, " (+", tostring(dcount_databases - 1), ")")),
          query_sql_text,
          count_executions,
          count_successful_executions,
          count_aborted_executions,
          count_exception_executions,
          duration_us,
          cpu_time_us,
          logical_io_reads,
          logical_io_writes,
          physical_io_reads,
          num_physical_io_reads,
          clr_time_us,
          dop,
          query_max_used_memory_kb = query_max_used_memory * 8,
          rowcount,
          log_bytes_used,
          tempdb_space_used_kb = tempdb_space_used * 8,
          sql_module_name = iif(dcount_sql_module_name == 1, any_sql_module_name, strcat(any_sql_module_name, " (+", tostring(dcount_sql_module_name - 1), ")")),
          context_settings_id = iif(dcount_context_settings_id == 1, tostring(any_context_settings_id), strcat(any_context_settings_id, " (+", tostring(dcount_context_settings_id - 1), ")")),
          query_hash
| sort by count_executions desc | extend count_executions_rank = row_rank_dense(count_executions)
| sort by duration_us desc | extend duration_rank = row_rank_dense(duration_us)
| sort by cpu_time_us desc | extend cpu_time_rank = row_rank_dense(cpu_time_us)
| sort by logical_io_reads desc | extend logical_io_reads_rank = row_rank_dense(logical_io_reads)
| sort by logical_io_writes desc | extend logical_io_writes_rank = row_rank_dense(logical_io_writes)
| sort by physical_io_reads desc | extend physical_io_reads_rank = row_rank_dense(physical_io_reads)
| sort by num_physical_io_reads desc | extend num_physical_io_reads_rank = row_rank_dense(num_physical_io_reads)
| sort by clr_time_us desc | extend clr_time_rank = row_rank_dense(clr_time_us)
| sort by dop desc | extend dop_rank = row_rank_dense(dop)
| sort by query_max_used_memory_kb desc | extend query_max_used_memory_rank = row_rank_dense(query_max_used_memory_kb)
| sort by rowcount desc | extend rowcount_rank = row_rank_dense(rowcount)
| sort by log_bytes_used desc | extend log_bytes_used_rank = row_rank_dense(log_bytes_used)
| sort by tempdb_space_used_kb desc | extend tempdb_space_used_rank = row_rank_dense(tempdb_space_used_kb)
| sort by case(
              topQueriesBy =~ "count_executions", toreal(count_executions),
              topQueriesBy =~ "duration", toreal(duration_us),
              topQueriesBy =~ "cpu_time", toreal(cpu_time_us),
              topQueriesBy =~ "logical_io_reads", toreal(logical_io_reads),
              topQueriesBy =~ "logical_io_writes", toreal(logical_io_writes),
              topQueriesBy =~ "physical_io_reads", toreal(physical_io_reads),
              topQueriesBy =~ "num_physical_io_reads", toreal(num_physical_io_reads),
              topQueriesBy =~ "clr_time", toreal(clr_time_us),
              topQueriesBy =~ "dop", toreal(dop),
              topQueriesBy =~ "query_max_used_memory", toreal(query_max_used_memory_kb),
              topQueriesBy =~ "rowcount", toreal(rowcount),
              topQueriesBy =~ "log_bytes_used", toreal(log_bytes_used),
              topQueriesBy =~ "tempdb_space_used", toreal(tempdb_space_used_kb),
              real(null)
              ) desc,
          count_executions desc
| project-away count_executions
| where isempty(queryHash) or query_hash == queryHash
| where isempty(queryTextFragment) or query_sql_text contains queryTextFragment
| take topQueries;

A KQL használata a teljesítményszámlálók időbeli elemzéséhez

Ebben a példában a lekérdezés a megadott befejezési idő előtt 30 perccel kezdődő időintervallum teljesítményszámláló értékeit adja vissza.

Ez a példa halmozott teljesítményszámlálókat használ, például Total request count és Query optimizations/sec. Az összegző érték azt jelenti, hogy a számláló értéke folyamatosan növekszik az SQL-lekérdezési tevékenység során. A példában szereplő lekérdezés kiszámítja az egyes minták számlálóértékének és az előző mintában szereplő értékének különbségét vagy eltérését az előző minta óta történt kérések és optimalizálások számának lekéréséhez, majd ezeket a metrikákat egy idődiagramon jeleníti meg.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let logicalServer = @"your-server-name";
let databaseName = @"your-database-name";
let replicaType = "Primary";
let endTime = datetime("2023-12-19 22:10:00");
let startTime = endTime - 30m;
sqldb_database_performance_counters_common
| where sample_time_utc between (startTime .. endTime)
| where logical_server_name =~ logicalServer
| where database_name =~ databaseName
| where replica_type =~ replicaType
| where cntr_type == 272696576 // restrict to cumulative counters
| where object_name =~ "Workload Group Stats" and counter_name in ("Total request count","Query optimizations/sec")
| project replica_id, sample_time_utc, object_name, counter_name, cntr_value
| sort by replica_id asc, counter_name asc, sample_time_utc asc
| extend delta_cntr_value = iif(cntr_value >= prev(cntr_value) and counter_name == prev(counter_name) and replica_id == prev(replica_id), cntr_value - prev(cntr_value), real(null)),
         delta_sample_time_utc = iif(sample_time_utc >= prev(sample_time_utc), datetime_diff("Millisecond", sample_time_utc, prev(sample_time_utc)), long(null))
| where isnotempty(delta_sample_time_utc)
| extend value = delta_cntr_value / delta_sample_time_utc * 1000
| summarize requests_per_sec = take_anyif(value, counter_name =~ "Total request count"),
            query_optimizations_per_sec = take_anyif(value, counter_name =~ "Query optimizations/sec")
            by sample_time_utc
| sort by sample_time_utc desc
| project sample_time_utc, requests_per_sec, query_optimizations_per_sec
| render timechart;

Az alábbi példa olyan időponthoz kötött teljesítményszámlálókra mutat, amelyek a legutóbb megfigyelt értéket jelentik, például Active memory grants count, Pending memory grants countés Processes blocked. Az időintervallum az utolsó 30 perc.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let logicalServer = @"your-server-name";
let databaseName = @"your-database-name";
let replicaType = "Primary";
let duration = 30m;
sqldb_database_performance_counters_common
| where sample_time_utc > ago(duration)
| where logical_server_name =~ logicalServer
| where database_name =~ databaseName
| where replica_type =~ replicaType
| where cntr_type == 65792 // restrict to point-in-time counters
| where (object_name =~ "General Statistics" and counter_name in ("Processes blocked"))
        or
        (object_name =~ "Resource Pool Stats" and counter_name in ("Active memory grants count","Pending memory grants count"))
| project sample_time_utc, counter_name, cntr_value
| render timechart;

Az alábbi példa a teljesítményszámlálók (részletes) adatkészletet használja az Azure SQL-adatbázisban lévő felhasználói és belső erőforráskészletek és munkaterhelési csoportok CPU-kihasználtságának diagramját elkészíteni. További információ: felhasználói számítási feladatok és belső folyamatok erőforrás-felhasználása.

A felhasználói számítási feladatok a SloSharedPool1 vagy UserPool erőforráskészletekben futnak, míg az összes többi erőforráskészletet különböző rendszerterhelésekhez használják.

Hasonlóképpen, a felhasználói számítási feladatok a UserPrimaryGroup.DBIdnevű számítási feladatok csoportjaiban futnak, míg az összes többi számítási feladatcsoportot különböző rendszerterhelésekhez használják. Az adatbázis-figyelő figyelési lekérdezései például a SQLExternalMonitoringGroup számítási feladatcsoportban futnak.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let logicalServer = @"your-server-name";
let databaseName = @"your-database-name";
let replicaType = "Primary";
let endTime = datetime("2023-12-19 22:10:00");
let startTime = endTime - 30m;
sqldb_database_performance_counters_detailed
| where sample_time_utc between (startTime .. endTime)
| where logical_server_name =~ logicalServer
| where database_name =~ databaseName
| where replica_type =~ replicaType
| where cntr_type == 537003264 // restrict to ratio percentage counters
| where object_name =~ "Resource Pool Stats" and counter_name in ("CPU usage %")
| project sample_time_utc, resource_pool = instance_name, cpu_percentage = cntr_value
| render timechart;

let logicalServer = @"your-server-name";
let databaseName = @"your-database-name";
let replicaType = "Primary";
let endTime = datetime("2023-12-19 22:10:00");
let startTime = endTime - 30m;
sqldb_database_performance_counters_detailed
| where sample_time_utc between (startTime .. endTime)
| where logical_server_name =~ logicalServer
| where database_name =~ databaseName
| where replica_type =~ replicaType
| where cntr_type == 537003264 // restrict to ratio percentage counters
| where object_name =~ "Workload Group Stats" and counter_name in ("CPU usage %")
| project sample_time_utc, workload_group = instance_name, cpu_percentage = cntr_value
| render timechart;

KQL használata a halmozott várakozások időbeli elemzéséhez

Ez a példa bemutatja, hogyan ábrázolhatók a leggyakoribb SQL-várakozási típusok egy időintervallumon belül. A lekérdezés kiszámítja az egyes várakozási típusok összesített várakozási idejét az eltelt idő másodpercenkénti ezredmásodpercében. A lekérdezési változók úgy módosíthatók, hogy megszabják az intervallum kezdő és záró időpontját, a maximális várakozási típusok számát, valamint a diagram adatpontjai közötti lépést.

A lekérdezés két technikával javítja a teljesítményt:

  • A partíció KQL-operátora a shuffle stratégiát alkalmazza, hogy a lekérdezés feldolgozását több fürtcsomópontra terjessze, ha azok rendelkezésre állnak.
  • A materializál() függvény megőrzi a köztes eredményhalmazt, amelyet újra felhasználnak a legnagyobb várakozási idők kiszámításához és a diagramon ábrázolandó idősor létrehozásához.
  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
let logicalServer = @"your-server-name";
let databaseName = @"your-database-name";
let replicaType = "Primary";
let endTime = datetime("2023-12-19 22:10:00");
let startTime = endTime - 30m;
let top_wait_types = 10;
let chart_step = 30s;
let wait_type_sample = materialize (
sqldb_database_wait_stats
| where sample_time_utc between (startTime .. endTime)
| where logical_server_name =~ logicalServer
| where database_name =~ databaseName
| where replica_type =~ replicaType
| project replica_id, sample_time_utc, wait_type, wait_time_ms
| partition hint.strategy=shuffle by wait_type
(
sort by replica_id asc, sample_time_utc asc
| extend delta_wait_time_ms = iif(wait_time_ms >= prev(wait_time_ms) and replica_id == prev(replica_id), wait_time_ms - prev(wait_time_ms), long(null)),
         delta_sample_time_utc = iif(sample_time_utc >= prev(sample_time_utc), datetime_diff("Millisecond", sample_time_utc, prev(sample_time_utc)), long(null))
| where isnotempty(delta_sample_time_utc)
| extend wait_ms_per_s = toreal(delta_wait_time_ms) / delta_sample_time_utc * 1000
| project sample_time_utc, wait_type, wait_ms_per_s
)
);
let top_wait = (
wait_type_sample
| summarize total_wait_ms_per_s = sum(wait_ms_per_s) by wait_type
| top top_wait_types by total_wait_ms_per_s desc
| project-away total_wait_ms_per_s
);
wait_type_sample
| join kind=inner top_wait on wait_type
| project-away wait_type1
| make-series wait_ms_per_s = avgif(wait_ms_per_s, isfinite(wait_ms_per_s)) default = long(null) on sample_time_utc from startTime to endTime step chart_step by wait_type
| project wait_type, sample_time_utc, wait_ms_per_s
| render timechart;

Monitorozási adatok elemzése a T-SQL használatával

Ha már ismeri a T-SQL-t, azonnal megkezdheti az SQL monitorozási adatainak lekérdezését és elemzését anélkül, hogy meg kellene tanulnia a KQL-t. Azonban KQL az Azure Data Explorerben vagy Real-Time Analyticsben az adatok lekérdezésének ajánlott nyelve, mivel páratlan támogatást nyújt a telemetriai adatok lekérdezéséhez.

Az Azure Data Explorerhez vagy a Real-Time Analytics-adatbázishoz való csatlakozáshoz használhatja az SQL Server Management Studio-t (SSMS), a Visual Studio Code-ot az SQL Server mssql bővítménnyel, valamint más gyakori eszközöket. Az Azure Data Explorert vagy a KQL-adatbázist úgy kérdezheti le, mintha SQL Server vagy Azure SQL-adatbázis lenne. További információ: Adatok lekérdezése az Azure Data Explorerben SQL Server-emulációshasználatával.

Jegyzet

Az Azure Data Explorer és Real-Time Analytics nem minden T-SQL-szerkezetet támogat. További információ: Adatok lekérdezése T-SQL-használatával.

A SQL-t Kusto Query Language-re átalakító puskázó kártya segíthet a T-SQL-lekérdezések KQL-re való fordításában, ha úgy találja, hogy a T-SQL-támogatás nem elegendő az igényeinek, vagy ha a T-SQL-lekérdezéseket KQL-vé szeretné konvertálni annak speciális elemzési képességeinek kihasználása érdekében.

Az alábbi példák bemutatják, hogyan kérdezhet le monitorozási adatokat a figyelő adattárában a T-SQL használatával.

A T-SQL használata az erőforrás-felhasználás időbeli elemzéséhez

Ebben a példában a lekérdezés erőforrás-használati metrikákat (CPU, feldolgozók, naplóírási teljesítmény stb.) ad vissza egy adatbázis, egy rugalmas készlet vagy egy felügyelt SQL-példány elsődleges replikájához az elmúlt egy órában.

Ebben és más példákban módosítsa a DECLARE utasítás változóit úgy, hogy azok megfeleljenek a kiszolgáló, adatbázis, rugalmas készlet vagy felügyelt SQL-példány nevének.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
DECLARE @LogicalServerName sysname = 'your-server-name',
        @DatabaseName sysname = 'your-database-name',
        @ReplicaType sysname = 'Primary',
        @DurationMinutes int = 60;

SELECT sample_time_utc,
       avg_cpu_percent,
       avg_instance_cpu_percent,
       avg_data_io_percent,
       avg_log_write_percent,
       max_worker_percent
FROM sqldb_database_resource_utilization
WHERE sample_time_utc > DATEADD(minute, -@DurationMinutes, SYSUTCDATETIME())
      AND
      logical_server_name = @LogicalServerName
      AND
      database_name = @DatabaseName
      AND
      replica_type = @ReplicaType
ORDER BY sample_time_utc DESC;

A T-SQL használata az adatbázis, a rugalmas készlet vagy a felügyelt SQL-példány tulajdonságainak megtekintéséhez

Ebben a példában a lekérdezés az összes olyan adatbázist, rugalmas készletet vagy felügyelt SQL-példányt ad vissza, amelyekből az elmúlt 24 órában legalább egy mintát gyűjtöttek a megfelelő Tulajdonságokadathalmazban. Más szóval minden sor egy monitorozási célt jelöl a legutóbb megfigyelt tulajdonságokkal.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
DECLARE @DurationHours int = 24;

SELECT p.sample_time_utc,
       p.logical_server_name,
       p.database_name,
       p.replica_type,
       p.database_id,
       p.elastic_pool_name,
       p.service_tier,
       p.service_level_objective,
       p.logical_cpu_count,
       p.database_engine_memory_mb,
       p.compatibility_level,
       p.updateability,
       p.database_engine_build_time,
       p.database_engine_start_time_utc
FROM sqldb_database_properties AS p
INNER JOIN (
           SELECT logical_server_name,
                  database_name,
                  replica_type,
                  MAX(sample_time_utc) AS last_sample_time_utc
           FROM sqldb_database_properties
           WHERE sample_time_utc > DATEADD(hour, -@DurationHours, SYSUTCDATETIME())
           GROUP BY logical_server_name,
                    database_name,
                    replica_type
           ) AS ls
ON p.logical_server_name = ls.logical_server_name
   AND
   p.database_name = ls.database_name
   AND
   p.replica_type = ls.replica_type
   AND
   p.sample_time_utc = ls.last_sample_time_utc
WHERE p.sample_time_utc > DATEADD(hour, -@DurationHours, SYSUTCDATETIME())
ORDER BY LOWER(logical_server_name) ASC,
         LOWER(database_name) ASC,
         CASE replica_type
              WHEN 'Primary' THEN 0
              WHEN 'Geo-replication forwarder' THEN 1
              WHEN 'Named secondary' THEN 2
              WHEN 'HA secondary' THEN 3
         END ASC;

A T-SQL használata a lekérdezési futtatókörnyezet statisztikáinak megtekintéséhez

Ez a lekérdezés az Azure SQL-tulajdonban lévő leggyakoribb erőforrás-használó lekérdezéseket adja vissza. Módosítsa a @TopQueriesBy változót úgy, hogy az Lekérdezéstár metrika alapján keresse meg a leggyakoribb lekérdezéseket, beleértve a processzoridőt, az eltelt időt, a végrehajtások számát stb. Beállíthat változókat úgy is, hogy egy adott lekérdezés időintervalluma, lekérdezés-végrehajtási típusa és lekérdezéskivonata alapján szűrjenek, vagy egy adott logikai kiszolgáló, rugalmas készlet vagy felügyelt SQL-példány adatbázisaira összpontosítsanak.

A lekérdezés a Lekérdezés futtatókörnyezeti statisztikáitadatkészletet használja a megadott leggyakoribb lekérdezések visszaadásához. Ez is visszaadja a rangjukat minden más erőforrás-fogyasztási metrika alapján.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
DECLARE @EndTime datetime2 = SYSUTCDATETIME(),
        @StartTime datetime2 = DATEADD(hour, -24, SYSUTCDATETIME()),
        /* 
        Set the next variable to one of the following metrics to return the top resource consuming queries:
        executions, cpu_time, duration, logical_io_reads, physical_io_reads, num_physical_io_reads, 
        clr_time, query_max_used_memory, log_bytes_used, tempdb_space_used, row_count, dop
        */
        @TopQueriesBy varchar(30) = 'cpu_time',
        @TopQueries int = 10,
        @LogicalServerName sysname = '', -- Optionally filter by logical server name
        @ElasticPoolName sysname = '', -- Optionally filter by elastic pool name, if any databases are in elastic pools
        @DatabaseName sysname = '', -- Optionally filter by database name
        @ExecutionType varchar(30) = '', -- Optionally filter by execution type. Use Regular, Aborted, Exception.
        @QueryHash varchar(18) = ''; -- Optionally filter by query hash (example: 0xBAAA461A6C93EA88)

SELECT TOP (@TopQueries) 
       CONCAT(logical_server_name, IIF(count_logical_servers > 1, CONCAT(' (+', CAST(count_logical_servers - 1 AS varchar(11)), ')'), '')) AS logical_server_name,
       CONCAT(database_name, IIF(count_databases > 1, CONCAT(' (+', CAST(count_databases - 1 AS varchar(11)), ')'), '')) AS database_name,
       query_sql_text,
       CONCAT(CAST(query_id AS varchar(11)), IIF(count_queries > 1, CONCAT(' (+', CAST(count_queries - 1 AS varchar(11)), ')'), '')) AS query_id,
       CONCAT(CAST(plan_id AS varchar(11)), IIF(count_plans > 1, CONCAT(' (+', CAST(count_plans - 1 AS varchar(11)), ')'), '')) AS plan_id,
       regular_executions,
       aborted_executions,
       exception_executions,
       cpu_time_us,
       duration_us,
       logical_io_reads,
       physical_io_reads,
       num_physical_io_reads,
       clr_time_us,
       query_max_used_memory_kb,
       log_bytes_used,
       tempdb_space_used_kb,
       row_count,
       dop,
       query_hash,
       executions_rank,
       cpu_time_rank,
       duration_rank,
       logical_io_reads_rank,
       physical_io_reads_rank,
       num_physical_io_reads_rank,
       clr_time_rank,
       query_max_used_memory_rank,
       log_bytes_used_rank,
       tempdb_space_used_rank,
       row_count_rank,
       dop_rank
FROM (
     SELECT *,
            DENSE_RANK() OVER (ORDER BY executions DESC) AS executions_rank,
            DENSE_RANK() OVER (ORDER BY cpu_time_us DESC) AS cpu_time_rank,
            DENSE_RANK() OVER (ORDER BY duration_us DESC) AS duration_rank,
            DENSE_RANK() OVER (ORDER BY logical_io_reads DESC) AS logical_io_reads_rank,
            DENSE_RANK() OVER (ORDER BY physical_io_reads DESC) AS physical_io_reads_rank,
            DENSE_RANK() OVER (ORDER BY num_physical_io_reads DESC) AS num_physical_io_reads_rank,
            DENSE_RANK() OVER (ORDER BY clr_time_us DESC) AS clr_time_rank,
            DENSE_RANK() OVER (ORDER BY query_max_used_memory_kb DESC) AS query_max_used_memory_rank,
            DENSE_RANK() OVER (ORDER BY log_bytes_used DESC) AS log_bytes_used_rank,
            DENSE_RANK() OVER (ORDER BY tempdb_space_used_kb DESC) AS tempdb_space_used_rank,
            DENSE_RANK() OVER (ORDER BY row_count DESC) AS row_count_rank,
            DENSE_RANK() OVER (ORDER BY dop DESC) AS dop_rank
     FROM (
          SELECT query_hash,
                 COUNT(DISTINCT(logical_server_name)) AS count_logical_servers,
                 MAX(logical_server_name) AS logical_server_name,
                 COUNT(DISTINCT(database_name)) AS count_databases,
                 MAX(database_name) AS database_name,
                 COUNT(DISTINCT(query_id)) AS count_queries,
                 MAX(query_id) AS query_id,
                 COUNT(DISTINCT(plan_id)) AS count_plans,
                 MAX(plan_id) AS plan_id,
                 MAX(query_sql_text) AS query_sql_text,
                 SUM(IIF(execution_type_desc = 'Regular', count_executions, 0)) AS regular_executions,
                 SUM(IIF(execution_type_desc = 'Aborted', count_executions, 0)) AS aborted_executions,
                 SUM(IIF(execution_type_desc = 'Exception', count_executions, 0)) AS exception_executions,
                 SUM(count_executions) AS executions,
                 SUM(avg_cpu_time_us * count_executions) AS cpu_time_us,
                 SUM(avg_duration_us * count_executions) AS duration_us,
                 SUM(avg_logical_io_reads * count_executions) AS logical_io_reads,
                 SUM(avg_physical_io_reads * count_executions) AS physical_io_reads,
                 SUM(avg_num_physical_io_reads * count_executions) AS num_physical_io_reads,
                 SUM(avg_clr_time_us * count_executions) AS clr_time_us,
                 SUM(avg_query_max_used_memory * count_executions) * 8 AS query_max_used_memory_kb,
                 SUM(avg_log_bytes_used * count_executions) AS log_bytes_used,
                 SUM(avg_tempdb_space_used * count_executions) * 8 AS tempdb_space_used_kb,
                 SUM(avg_rowcount * count_executions) AS row_count,
                 SUM(IIF(is_parallel_plan = 1, avg_dop * count_executions, NULL)) AS dop
          FROM sqldb_database_query_runtime_stats
          WHERE interval_start_time >= @StartTime AND interval_end_time <= @EndTime
                AND
                (@ExecutionType = '' OR LOWER(execution_type_desc) = LOWER(@ExecutionType))
                AND
                (@LogicalServerName = '' OR LOWER(logical_server_name) = LOWER(@LogicalServerName))
                AND
                (@ElasticPoolName = '' OR LOWER(elastic_pool_name) = LOWER(@ElasticPoolName))
                AND
                (@DatabaseName = '' OR LOWER(database_name) = LOWER(@DatabaseName))
          GROUP BY query_hash
          ) AS rsa
     ) AS rsar
WHERE @QueryHash = '' OR LOWER(query_hash) = LOWER(@QueryHash)
ORDER BY CASE @TopQueriesBy
              WHEN 'executions' THEN executions_rank
              WHEN 'cpu_time' THEN cpu_time_rank
              WHEN 'duration' THEN duration_rank
              WHEN 'logical_io_reads' THEN logical_io_reads_rank
              WHEN 'physical_io_reads' THEN physical_io_reads_rank
              WHEN 'num_physical_io_reads' THEN num_physical_io_reads_rank
              WHEN 'clr_time' THEN clr_time_rank
              WHEN 'query_max_used_memory' THEN query_max_used_memory_rank
              WHEN 'log_bytes_used' THEN log_bytes_used_rank
              WHEN 'tempdb_space_used' THEN tempdb_space_used_rank
              WHEN 'row_count' THEN row_count_rank
              WHEN 'dop' THEN dop_rank
         END ASC;

A T-SQL használata a teljesítményszámlálók időbeli elemzéséhez

Ebben a példában a lekérdezés az elmúlt 30 perc teljesítményszámláló értékeit adja vissza.

Ez a példa halmozott teljesítményszámlálókat használ, például Total request count és Query optimizations/sec. Az összegző érték azt jelenti, hogy a számláló értéke folyamatosan növekszik a lekérdezési tevékenység során. A lekérdezés a LAG() elemzési függvényt használja az egyes minták számlálóértékének és az előző mintában lévő értékének különbségének vagy különbözetének kiszámításához az előző minta óta történt kérelmek és optimalizálások számának kiszámításához.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
DECLARE @LogicalServerName sysname = 'your-server-name',
        @DatabaseName sysname = 'your-database-name',
        @ReplicaType sysname = 'Primary',
        @DurationMinutes int = 30;

SELECT sample_time_utc,
       SUM(IIF(
              counter_name = 'Total request count',
              CAST((cntr_value - prev_cntr_value) AS decimal) / DATEDIFF(millisecond, prev_sample_time_utc, sample_time_utc) * 1000,
              NULL
              )) AS requests_per_second,
       SUM(IIF(
              counter_name = 'Query optimizations/sec',
              CAST((cntr_value - prev_cntr_value) AS decimal) / DATEDIFF(millisecond, prev_sample_time_utc, sample_time_utc) * 1000,
              NULL
              )) AS query_optimizations_per_second
FROM (
     SELECT sample_time_utc,
            LAG(sample_time_utc) OVER (PARTITION BY replica_id, object_name, counter_name ORDER BY sample_time_utc ASC) AS prev_sample_time_utc,
            counter_name,
            cntr_value,
            LAG(cntr_value) OVER (PARTITION BY replica_id, object_name, counter_name ORDER BY sample_time_utc ASC) AS prev_cntr_value
     FROM sqldb_database_performance_counters_common
     WHERE sample_time_utc > DATEADD(minute, -@DurationMinutes, SYSUTCDATETIME())
           AND
           logical_server_name = @LogicalServerName
           AND
           database_name = @DatabaseName
           AND
           replica_type = @ReplicaType
           AND
           cntr_type = 272696576 /* restrict to cumulative counters */
           AND
           object_name = 'Workload Group Stats'
           AND
           counter_name IN ('Total request count','Query optimizations/sec')
     ) AS pc
WHERE cntr_value >= prev_cntr_value
      AND
      sample_time_utc >= prev_sample_time_utc
GROUP BY sample_time_utc
ORDER BY sample_time_utc DESC;

A T-SQL használata időponthoz kötött teljesítményszámlálók elemzéséhez

A következő példa az időponthoz kötött teljesítményszámlálókra, amelyek a legutóbb megfigyelt értéket jelentik , például Active memory grants count, Pending memory grants countés Processes blocked.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
DECLARE @LogicalServerName sysname = 'your-server-name',
        @DatabaseName sysname = 'your-database-name',
        @ReplicaType sysname = 'Primary',
        @DurationMinutes int = 30;

SELECT sample_time_utc,
       SUM(IIF(
              counter_name = 'Processes blocked',
              cntr_value,
              NULL
              )) AS processes_blocked,
       SUM(IIF(
              counter_name = 'Active memory grants count',
              cntr_value,
              NULL
              )) AS active_memory_grants,
       SUM(IIF(
              counter_name = 'Pending memory grants count',
              cntr_value,
              NULL
              )) AS pending_memory_grants
FROM (
     SELECT sample_time_utc,
            counter_name,
            cntr_value
     FROM sqldb_database_performance_counters_common
     WHERE sample_time_utc > DATEADD(minute, -@DurationMinutes, SYSUTCDATETIME())
         AND
         logical_server_name = @LogicalServerName
         AND
         database_name = @DatabaseName
         AND
         replica_type = @ReplicaType
         AND
         cntr_type = 65792 /* restrict to point-in-time counters */
         AND
         (
         (object_name = 'General Statistics' AND counter_name IN ('Processes blocked'))
         OR
         (object_name = 'Resource Pool Stats' AND counter_name IN ('Active memory grants count','Pending memory grants count'))
         )
     ) AS pc
GROUP BY sample_time_utc
ORDER BY sample_time_utc DESC;

A T-SQL használata a halmozott várakozások időbeli elemzéséhez

Ebben a példában a lekérdezés az első 10 várakozási típust adja vissza az átlagos halmozott várakozási idő alapján egy 30 perces intervallumban. Az összegző azt jelenti, hogy a lekérdezés ezredmásodpercben kiszámítja az egyes várakozási típusok szerinti várakozással töltött időt minden másodpercenkénti kérés alapján. Mivel egyszerre több kérés is végrehajtható (és várakozhat), a másodpercenkénti összesített várakozási idő több mint egy másodperc lehet.

  • SQL-adatbázis
  • SQL rugalmas erőforráskészlet
  • felügyelt SQL-példány
DECLARE @LogicalServerName sysname = 'your-server-name',
        @DatabaseName sysname = 'your-database-name',
        @ReplicaType sysname = 'Primary',
        @DurationMinutes int = 30;

SELECT TOP (10) wait_type,
                SUM(CAST((wait_time_ms - prev_wait_time_ms) AS decimal)) * 1000
                /
                SUM(DATEDIFF(millisecond, prev_sample_time_utc, sample_time_utc))
                AS wait_time_ms_per_sec
FROM (
     SELECT sample_time_utc,
            LAG(sample_time_utc) OVER (PARTITION BY replica_id, wait_type ORDER BY sample_time_utc ASC) AS prev_sample_time_utc,
            wait_type,
            wait_time_ms,
            LAG(wait_time_ms) OVER (PARTITION BY replica_id, wait_type ORDER BY sample_time_utc ASC) AS prev_wait_time_ms
     FROM sqldb_database_wait_stats
     WHERE sample_time_utc > DATEADD(minute, -@DurationMinutes, SYSUTCDATETIME())
         AND
         logical_server_name = @LogicalServerName
         AND
         database_name = @DatabaseName
         AND
         replica_type = @ReplicaType
     ) AS w
WHERE sample_time_utc >= prev_sample_time_utc
      AND
      wait_time_ms >= prev_wait_time_ms
GROUP BY wait_type
ORDER BY wait_time_ms_per_sec DESC;