Skip to content
Learni
View all tutorials
Cloud & Bases de données

How to Deploy and Optimize Azure SQL Database in 2026

Lire en français

Introduction

Azure SQL Database is Microsoft's managed PaaS for SQL Server in the cloud, offering unmatched horizontal and vertical scalability. In 2026, with the rise of AI and massive workloads, mastering advanced deployment is essential for architects: Hyperscale for terabytes of data, serverless for auto-scaling, active geo-replication for disaster recovery, and Query Store for automatic optimization.

This advanced tutorial guides you step by step, from IaC provisioning to fine-tuning, with complete, functional code (Azure CLI, SQL, Bicep). You'll create a Hyperscale DB, set up Zero Trust security, tune performance with Intelligent Insights, and monitor in real time. By the end, you'll have a production-ready architecture scalable to 100 TB, resilient, and optimized to reduce costs by 40%. Built for pros who bookmark: zero fluff, 100% actionable. (128 words)

Prerequisites

  • Active Azure account with subscription (credits are enough for testing).
  • Azure CLI 2.65+ installed (download).
  • PowerShell 7+ for advanced scripts.
  • Azure Data Studio or SSMS to run SQL.
  • Advanced SQL Server knowledge (indexing, query plans) and ARM/Bicep.
  • Nearby Azure region (e.g., France Central).

Install Azure CLI and connect

terminal.sh
az login
az account set --subscription "VotreSubscriptionID"
az version

This script authenticates your Azure CLI session and selects the subscription. Replace VotreSubscriptionID with your real ID (found via az account list). Avoids multi-account auth pitfalls by setting explicitly; verify with az version to confirm CLI >=2.65.

Create the Resource Group and SQL Server

We'll provision a resource group and an Azure SQL logical server with SQL authentication (admin/password). Use Bicep for declarative IaC—more modern than ARM JSON.

Deploy server via Bicep

main.bicep
param location string = resourceGroup().location
param sqlAdmin string = 'sqladmin2026'
param sqlPassword string {
  @secure()
  minLength: 12
}

resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' Existing = {
  name: resourceGroup().name
}

resource sqlServer 'Microsoft.Sql/servers@2023-05-01-preview' = {
  name: 'sqlserver-${uniqueString(resourceGroup().id)}'
  location: location
  properties: {
    administratorLogin: sqlAdmin
    administratorLoginPassword: sqlPassword
    version: '16.0'
  }
}

output serverName string = sqlServer.name
output fullServerName string = '${sqlServer.name}.database.windows.net'

This Bicep template creates a SQL Server v16 with secure admin. @secure() masks the password param. Deploy with az deployment group create --resource-group MonRG --template-file main.bicep --parameters sqlPassword=MonPassSecurise123!. Pitfall: Use version '16.0' for Hyperscale compatibility.

Deploy the Bicep (CLI)

deploy.sh
az group create --name "rg-sql-advanced-2026" --location "francecentral"
az deployment group create --resource-group "rg-sql-advanced-2026" --template-file main.bicep --parameters sqlPassword='P@ssw0rdAvance2026!SqlDb' --query properties.outputs.serverName.value -o tsv

Creates the RG and deploys the server. Captures serverName output for next steps (e.g., myserverabc.database.windows.net). Password must meet Azure complexity (12+ chars, upper/lower/number/special). Avoids region errors by specifying francecentral.

Create a Hyperscale DB and configure firewall

Provision a Hyperscale DB (native scale-out to 100 TB) and open the firewall for your IP. Hyperscale shines for massive OLTP workloads with distributed compute pools.

Create Hyperscale DB and firewall

create-db.sh
SERVER_NAME=$(az deployment group show --resource-group "rg-sql-advanced-2026" --name "bicep-deployment" --query properties.outputs.serverName.value -o tsv)

az sql db create --resource-group "rg-sql-advanced-2026" --server $SERVER_NAME --name "hyperscale-db-2026" --service-objective "HS_Gen5_2" --family "Gen5" --edition Hyperscale

az sql server firewall-rule create --resource-group "rg-sql-advanced-2026" --server $SERVER_NAME --name AllowMyIP --start-ip-address $(curl -s ifconfig.me) --end-ip-address $(curl -s ifconfig.me)

Creates a Gen5 Hyperscale DB with 2 initial vCores. HS_Gen5_2 = scalable SKU. Firewall rule for your public IP (via ifconfig.me). Pitfall: Hyperscale requires --edition Hyperscale; scale later via portal/CLI.

Connect and create initial schema

init-schema.sql
USE [hyperscale-db-2026];
GO

CREATE TABLE Users (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Email NVARCHAR(255) NOT NULL UNIQUE,
    CreatedAt DATETIME2 DEFAULT SYSDATETIMEOFFSET()
);
GO

CREATE INDEX IX_Users_Email ON Users(Email) INCLUDE (CreatedAt);
GO

CREATE TABLE Orders (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    UserId INT NOT NULL,
    Amount DECIMAL(10,2),
    OrderDate DATETIME2 DEFAULT SYSDATETIMEOFFSET(),
    FOREIGN KEY (UserId) REFERENCES Users(Id)
);
GO

INSERT INTO Users (Email) VALUES ('test@exemple.com');
INSERT INTO Orders (UserId, Amount) VALUES (1, 99.99);
GO

Run via Azure Data Studio (connection: server=$SERVER_NAME, db=hyperscale-db-2026, user=sqladmin2026, pass=P@ssw0rd...). Creates OLTP tables with FKs and columnstore-like index. Pitfall: IDENTITY for auto-increment, SYSDATETIMEOFFSET for UTC-aware timestamps.

Secure with Auditing and TDE

Enable blob storage auditing, Transparent Data Encryption (TDE), and Advanced Threat Protection for Zero Trust.

Enable advanced security

security.sh
SERVER_NAME=$(az deployment group show --resource-group "rg-sql-advanced-2026" --name "bicep-deployment" --query properties.outputs.serverName.value -o tsv)

# Auditing to Log Analytics
az sql server create-audit-policy --resource-group rg-sql-advanced-2026 --server $SERVER_NAME --state Enabled --storage-key-type ServiceManaged

# TDE
az sql db tde set --resource-group rg-sql-advanced-2026 --server $SERVER_NAME --database-name hyperscale-db-2026 --status Enabled

# Threat Detection
az sql server advanced-threat-protection-settings create --resource-group rg-sql-advanced-2026 --server $SERVER_NAME --state Enabled --retention-days 90 --storage-endpoint 'https://mystorageacct.blob.core.windows.net/blobcontainer/'

Auditing to Log Analytics (service-managed). TDE encrypts data at rest. ATP detects SQL injection. Pitfall: Provide a valid storage endpoint for ATP; retain 90 days for GDPR compliance.

Set up active geo-replication

geo-rep.sh
SERVER_NAME=$(az deployment group show --resource-group "rg-sql-advanced-2026" --name "bicep-deployment" --query properties.outputs.serverName.value -o tsv)

az sql db replica create --resource-group rg-sql-advanced-2026 --server $SERVER_NAME --name geo-replica-db --partner-server myserver-secondary.database.windows.net --service-objective HS_Gen5_4

az sql db failover --resource-group rg-sql-advanced-2026 --server myserver-secondary.database.windows.net --name geo-replica-db

Creates active geo-replica for RPO=0s, RTO<1min. Manual failover for DR. Scale secondary to 4 vCores. Pitfall: Pre-create secondary server; use for cross-region HA (e.g., France Central -> West Europe).

Optimize performance with Query Store

Query Store (enabled by default) + Automatic Tuning for smart indexes. Analyze and force plans.

Query Store queries and auto-tuning

query-optimize.sql
-- Activer Automatic Tuning
ALTER DATABASE [hyperscale-db-2026] SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = ON, CREATE_INDEX = ON, DROP_INDEX = ON);
GO

-- Top queries by CPU
SELECT TOP 10
    qt.query_sql_text,
    rs.avg_cpu_time,
    rs.count_executions
FROM sys.query_store_query_text qt
JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan p ON q.query_id = p.query_id
JOIN sys.query_store_runtime_stats rs ON p.plan_id = rs.plan_id
ORDER BY rs.avg_cpu_time DESC;
GO

-- Créer index recommandé
CREATE INDEX IX_Orders_UserId_Amount ON Orders(UserId) INCLUDE (Amount, OrderDate);
GO

Enables auto-tuning: forces stable plans, creates/drops indexes. Queries top CPU for bottlenecks. Pitfall: avg_cpu_time in µs; run post-load for real insights.

Best practices

  • Always use IaC: Bicep/ARM for reproducibility; integrate with GitHub Actions.
  • Serverless scaling for variable workloads: --compute-model Serverless --min-capacity 0.5 --max-capacity 4.
  • Pro monitoring: Azure Monitor + Query Performance Insight; alerts on DTU/CPU >80%.
  • Custom backups: PITR up to 35 days; geo-restore for DR.
  • Cost optimization: Auto-pause after 1h idle, reserved capacity for -65%.

Common errors to avoid

  • Forget firewall: DB inaccessible after creation; always add IP rule or VNet.
  • Incompatible SKU: Hyperscale rejects General Purpose; check --edition.
  • No connection string pooling: Use Pooling=true;Min Pool Size=5 in apps.
  • Ignore Query Store: Without tuning, CPU spikes x10; query regularly.

Next steps