This article explores migration of 200GB SQL Server database used in e-commerce application to PostgreSQL for cost savings, open-source flexibility, and better performance on analytical queries.
Table of Contents
| Attribute | Value |
| Database Size | 200GB |
| Main Tables | Orders (50M rows), Customers (10M rows), Products (500K rows) |
| Indexes | 120+ |
| Stored Procedures | 150+ T-SQL Procedures |
| Transactions/sec | 4,000 |
| Average Query Response Time | 180ms |
First step of migration is schema conversion (tables, constraints, indexes, and stored procedures) into PostgreSQL format. Key challenge of schema conversion:
In MS SQL:
CREATE TABLE Orders (
ID INT IDENTITY(1,1) PRIMARY KEY,
OrderDate DATETIME DEFAULT GETDATE(),
IsPaid BIT DEFAULT 0
);
In PostgreSQL:
CREATE TABLE Orders (
ID SERIAL PRIMARY KEY,
OrderDate TIMESTAMP DEFAULT NOW(),
IsPaid BOOLEAN DEFAULT FALSE
);
The goal of this step is to migrate all records from SQL Server to PostgreSQL without data loss. MSSQL-to-PostgreSQL converter has been used for both schema and data migration and it gave the benchmark as follows (stats for main tables only):
| Table | Row Count | Time of Migration |
| Customers | 10M | 36 minutes |
| Orders | 50M | 4 hours 20 min |
| Products | 500K | 3 minutes |
MS SQL T-SQL procedures and functions have to be converted to PL/pgSQL in PostgreSQL. Key bottlenecks of this stage:
Triggers are database-level mechanisms that execute automatically when specific events occur, such as INSERT, UPDATE, or DELETE operations. While both MS SQL Server and PostgreSQL support triggers, there are differences in syntax, behavior, and implementation that must be accounted for during migration.
Key Differences:
Example of Migration
In MS SQL:
CREATE TRIGGER trg_AfterInsertOrders
ON Orders
AFTER INSERT
AS
BEGIN
UPDATE Customers
SET TotalOrders = TotalOrders + 1
FROM Customers C
INNER JOIN INSERTED I ON C.ID = I.CustomerID;
END;
PostgreSQL Equivalent:
CREATE OR REPLACE FUNCTION trg_AfterInsertOrders()
RETURNS TRIGGER AS $$
BEGIN
UPDATE Customers
SET TotalOrders = TotalOrders + 1
WHERE ID = NEW.CustomerID;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_AfterInsertOrders
AFTER INSERT ON Orders
FOR EACH ROW EXECUTE FUNCTION trg_AfterInsertOrders();
To ensure queries run efficiently in PostgreSQL, we compared query speeds before and after migration.
Bottlenecks Encountered:
This case study of successful migration from MS SQL to PostgreSQL demonstrates that with the proper tools and performance tests Postgres can be a cost-effective and high-performance alternative to SQL Server.
Key Takeaways:
Artificial Intelligence (AI) is no longer a futuristic concept—it’s now a driving force behind nearly…
Many bloggers struggle with low traffic and engagement despite consistently publishing content. This common frustration…
Today’s clients don’t just want results – they want to see the process. They expect…
Tailored IoT, fleet, and enterprise SIM solutions for seamless global communication Flexible, Scalable, and Reliable…
Cricket on a phone should feel simple – tap, watch, enjoy. Lag, hot batteries, and…
In today’s fast-paced digital economy, data has become the new currency driving decision-making and innovation…