| name | data-virtualization |
| description | Implement data virtualisation to query distributed data sources without moving data. Outputs virtual layer design, query federation strategy, performance optimisation, and governance approach. |
| argument-hint | ["data sources","query latency requirements","data volume","existing data infrastructure"] |
| allowed-tools | Read, Write |
Data Virtualization
Data virtualisation presents a unified logical view of data from multiple heterogeneous sources — without physically moving or replicating the data. Instead of ETL pipelines that copy data into a central warehouse, virtual layers query data in-place. This reduces latency for time-sensitive data and eliminates the complexity of replication pipelines.
When to Use Data Virtualization
USE VIRTUALIZATION when:
✓ Real-time or near-real-time data needed (can't wait for ETL)
✓ Data cannot be replicated (regulatory: GDPR data residency)
✓ Source system data used only occasionally (not worth ETL investment)
✓ Proof-of-concept before building full pipeline
✓ Federated query across multiple data warehouses
USE ETL/ELT instead when:
✓ Heavy transformations needed (virtualisation adds latency)
✓ Offline analytics (source systems unavailable 24/7)
✓ Historical analysis requires data retention beyond source
✓ Query performance is critical (virtualisation adds overhead)
✓ Complex ML feature computation
Query Federation with Trino
SELECT
p.customer_id,
p.email,
s.total_orders,
s.lifetime_value,
h.page_view_count
FROM postgresql.production.customers p
JOIN snowflake.analytics.customer_metrics s
ON p.customer_id = s.customer_id
JOIN hive.raw_events.page_views h
ON p.customer_id = h.user_id
WHERE p.created_at > DATE '2024-01-01'
AND s.total_orders > 5;
connector.name=postgresql
connection-url=jdbc:postgresql://prod-db:5432/production
connection-user=trino_reader
connection-password=${ENV:POSTGRES_PASSWORD}
connector.name=snowflake
connection-url=jdbc:snowflake://account.snowflakecomputing.com/
connection-user=trino_reader
connection-password=${ENV:SNOWFLAKE_PASSWORD}
snowflake.warehouse=ANALYTICS_WH
snowflake.database=ANALYTICS
connector.name=hive
hive.metastore.uri=thrift://hive-metastore:9083
hive.s3.aws-access-key=${ENV:AWS_ACCESS_KEY}
hive.s3.aws-secret-key=${ENV:AWS_SECRET_KEY}
dbt + Virtualisation
{{
config(
materialized='view',
schema='virtual_layer'
)
}}
WITH live_customers AS (
SELECT
customer_id,
email,
plan_type,
created_at
FROM {{ source('postgresql', 'customers') }}
WHERE created_at >= CURRENT_DATE - INTERVAL '90' DAY
),
analytics_enrichment AS (
SELECT
customer_id,
total_orders,
lifetime_value,
last_order_date
FROM {{ source('snowflake', 'customer_metrics') }}
)
SELECT
lc.customer_id,
lc.email,
lc.plan_type,
ae.total_orders,
ae.lifetime_value,
ae.last_order_date,
CASE
WHEN ae.last_order_date > CURRENT_DATE - INTERVAL '30' DAY THEN 'active'
WHEN ae.last_order_date > CURRENT_DATE -
customer_status
live_customers lc
analytics_enrichment ae (customer_id)
Performance Optimisation
EXPLAIN
SELECT * FROM postgresql.production.orders
WHERE created_at > DATE '2024-01-01'
AND status = 'paid';
CREATE TABLE snowflake.analytics.customer_360_snapshot AS
SELECT * FROM trino_virtual_layer.customer_360
WHERE last_order_date >= CURRENT_DATE - INTERVAL '30' DAY;
SELECT customer_id, email, plan_type
FROM postgresql.production.customers;
SELECT *
FROM hive.events.page_views
WHERE dt = '2024-03-15'
AND event_type ;
Anti-Patterns to Avoid
| Anti-Pattern | Problem | Fix |
|---|
| Virtualising everything | High latency; source systems overloaded | Virtualise for real-time; ETL for historical/heavy analytics |
| No query limits | Expensive federated queries cause source outages | Query timeout; row limits; connection pooling |
| SELECT * on virtual tables | Fetches all columns from source | Always specify required columns |
| Joining large virtual tables | Massive cross-source data movement | Pre-aggregate at source; use virtual layer for final join |
| No governance on virtual layer | PII in virtual views accessible to all | Apply column-level security at virtual layer |
10 Rules
- Data virtualisation is for real-time access and federation — not for replacing ETL at scale.
- Always push predicates (WHERE clauses) to source systems — verify with EXPLAIN.
- Never SELECT * from a virtual table — specify only required columns.
- Materialise frequently-queried virtual views for performance — refreshed on a schedule.
- Set query timeouts and row limits — runaway federated queries can take down source systems.
- Governance applies at the virtual layer — column-level security filters PII before users query.
- Source systems must be designed for additional read load — virtualisation adds queries.
- Trino/Presto is the most mature open-source federation engine — preferred over building custom.
- Latency budgets: virtual queries take 10-100x longer than warehouse queries — plan accordingly.
- Test query plans with EXPLAIN before production deployment — unexpected full scans are common.