MySQL & MariaDB
MySQL & MariaDB Integration
Section titled “MySQL & MariaDB Integration”Connect Querri to your MySQL or MariaDB database to run queries, analyze data, and create visualizations.
Overview
Section titled “Overview”The MySQL connector supports:
- MySQL 5.7+: All modern MySQL versions
- MySQL 8.0+: Full support including new features
- MariaDB 10.x: All MariaDB versions
- AWS RDS MySQL: Managed MySQL on AWS
- Azure Database for MySQL: Managed MySQL on Azure
- Google Cloud SQL for MySQL: Managed MySQL on GCP
Prerequisites
Section titled “Prerequisites”- MySQL or MariaDB database server
- Database credentials with appropriate permissions
- Network access to the database
IP Whitelisting
Section titled “IP Whitelisting”Important: For cloud-hosted databases or databases behind firewalls, whitelist the following IP address:
18.189.33.77This is Querri’s outbound IP address. Add this to your database firewall rules or security group.
Creating the Connector
Section titled “Creating the Connector”-
Navigate to Connectors
- Go to Settings → Connectors
- Click “Add Connector”
-
Select MySQL
- Choose “MySQL” from the database connectors
-
Configure Connection
Host: your-database-host.comPort: 3306 (default MySQL port)Database: your_database_nameUsername: your_usernamePassword: your_passwordOptional Settings:
- SSL: Enable for encrypted connections
- Charset: Default is
utf8mb4 - Connection Timeout: Default is 30 seconds
-
Test Connection
- Click “Test Connection” to verify
- If successful, click “Save”
-
Use in Projects
- Create a new step → “Database Query”
- Select your MySQL connector
- Write your SQL query
Network Configuration
Section titled “Network Configuration”AWS RDS Security Groups
Section titled “AWS RDS Security Groups”Add inbound rule:
Type: MySQL/AuroraProtocol: TCPPort: 3306Source: 18.189.33.77/32Description: Querri AccessAzure MySQL Firewall
Section titled “Azure MySQL Firewall”Add firewall rule:
Rule Name: QuerriStart IP: 18.189.33.77End IP: 18.189.33.77Google Cloud SQL
Section titled “Google Cloud SQL”Add authorized network:
Name: QuerriNetwork: 18.189.33.77/32Database User Setup
Section titled “Database User Setup”Read-Only User (Recommended)
Section titled “Read-Only User (Recommended)”Create a dedicated read-only user for Querri:
-- Create userCREATE USER 'querri_readonly'@'%'IDENTIFIED BY 'secure_password_here';
-- Grant read permissionsGRANT SELECT ON your_database.* TO 'querri_readonly'@'%';
-- Apply changesFLUSH PRIVILEGES;Read-Write User (If Needed)
Section titled “Read-Write User (If Needed)”For data updates or inserts:
-- Create userCREATE USER 'querri_readwrite'@'%'IDENTIFIED BY 'secure_password_here';
-- Grant read-write permissionsGRANT SELECT, INSERT, UPDATE, DELETE ON your_database.* TO 'querri_readwrite'@'%';
-- Apply changesFLUSH PRIVILEGES;Verify User Permissions
Section titled “Verify User Permissions”-- Show user grantsSHOW GRANTS FOR 'querri_readonly'@'%';
-- Test user can connectmysql -u querri_readonly -p -h your-host your_databaseExample Queries
Section titled “Example Queries”Basic SELECT
Section titled “Basic SELECT”SELECT customer_id, customer_name, email, created_atFROM customersWHERE status = 'active'ORDER BY created_at DESCLIMIT 100;Aggregate Query
Section titled “Aggregate Query”SELECT DATE_FORMAT(order_date, '%Y-%m') as month, COUNT(*) as order_count, SUM(total_amount) as total_revenue, AVG(total_amount) as avg_order_valueFROM ordersWHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)GROUP BY DATE_FORMAT(order_date, '%Y-%m')ORDER BY month DESC;JOIN Query
Section titled “JOIN Query”SELECT c.customer_name, c.email, COUNT(o.order_id) as order_count, SUM(o.total_amount) as lifetime_valueFROM customers cLEFT JOIN orders o ON c.customer_id = o.customer_idWHERE c.status = 'active'GROUP BY c.customer_id, c.customer_name, c.emailHAVING COUNT(o.order_id) > 0ORDER BY lifetime_value DESCLIMIT 50;Subquery Example
Section titled “Subquery Example”SELECT product_name, category, price, (SELECT AVG(price) FROM products p2 WHERE p2.category = p1.category) as avg_category_priceFROM products p1WHERE price > ( SELECT AVG(price) FROM products p3 WHERE p3.category = p1.category)ORDER BY category, price DESC;Performance Optimization
Section titled “Performance Optimization”Use Indexes
Section titled “Use Indexes”Ensure frequently queried columns have indexes:
CREATE INDEX idx_orders_customer ON orders(customer_id);CREATE INDEX idx_orders_date ON orders(order_date);CREATE INDEX idx_customers_email ON customers(email);Check Index Usage
Section titled “Check Index Usage”SHOW INDEX FROM orders;
-- See query execution planEXPLAIN SELECT * FROM orders WHERE customer_id = 123;Limit Result Sets
Section titled “Limit Result Sets”Always use LIMIT for large tables:
SELECT * FROM large_tableLIMIT 1000;Use Query Parameters
Section titled “Use Query Parameters”For repeated queries with different values:
SELECT * FROM ordersWHERE customer_id = {{customer_id}}AND order_date BETWEEN {{start_date}} AND {{end_date}};Common Use Cases
Section titled “Common Use Cases”Daily Sales Report
Section titled “Daily Sales Report”SELECT DATE(order_date) as date, COUNT(*) as orders, SUM(total_amount) as revenue, AVG(total_amount) as avg_order_valueFROM ordersWHERE order_date >= CURDATE() - INTERVAL 30 DAYGROUP BY DATE(order_date)ORDER BY date DESC;Customer Segmentation
Section titled “Customer Segmentation”SELECT CASE WHEN total_orders >= 10 THEN 'VIP' WHEN total_orders >= 5 THEN 'Regular' ELSE 'New' END as segment, COUNT(*) as customer_count, AVG(lifetime_value) as avg_ltvFROM ( SELECT c.customer_id, COUNT(o.order_id) as total_orders, COALESCE(SUM(o.total_amount), 0) as lifetime_value FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id) as customer_statsGROUP BY segment;Inventory Alert
Section titled “Inventory Alert”SELECT product_name, current_stock, reorder_level, supplier_name, CASE WHEN current_stock = 0 THEN 'OUT OF STOCK' WHEN current_stock <= reorder_level THEN 'REORDER NEEDED' WHEN current_stock <= reorder_level * 1.5 THEN 'LOW STOCK' ELSE 'OK' END as statusFROM inventoryLEFT JOIN suppliers ON inventory.supplier_id = suppliers.supplier_idWHERE current_stock <= reorder_level * 2ORDER BY current_stock ASC;Troubleshooting
Section titled “Troubleshooting”Connection Refused
Section titled “Connection Refused”Problem: Can’t connect to MySQL server
Solutions:
- Verify IP
18.189.33.77is whitelisted - Check MySQL is running:
systemctl status mysql - Verify bind-address allows remote connections
- Check firewall rules
- Verify host and port are correct
Access Denied
Section titled “Access Denied”Problem: Access denied for user
Solutions:
- Double-check username and password
- Verify user exists:
SELECT user, host FROM mysql.user; - Check user permissions:
SHOW GRANTS FOR 'username'@'host'; - Ensure user is created with correct host (
%for any host) - Run
FLUSH PRIVILEGES;after grant changes
Unknown Database
Section titled “Unknown Database”Problem: Unknown database error
Solutions:
- Verify database name is correct
- List databases:
SHOW DATABASES; - Ensure user has access to database
- Check for typos in database name
Too Many Connections
Section titled “Too Many Connections”Problem: Too many connections error
Solutions:
- Check current connections:
SHOW PROCESSLIST; - Increase max_connections:
SET GLOBAL max_connections = 200; - Close idle connections
- Optimize connection pooling settings
Query Timeout
Section titled “Query Timeout”Problem: Query takes too long
Solutions:
- Add indexes to queried columns
- Use LIMIT to reduce result set
- Optimize with EXPLAIN
- Increase
wait_timeoutandinteractive_timeout - Consider creating summary tables
Security Best Practices
Section titled “Security Best Practices”Use Read-Only Credentials
Section titled “Use Read-Only Credentials”Create dedicated read-only users for analytics to prevent accidental data modification.
Enable SSL
Section titled “Enable SSL”For production databases, enable SSL:
-- Require SSL for userALTER USER 'querri_readonly'@'%' REQUIRE SSL;FLUSH PRIVILEGES;In connector settings:
SSL: EnabledRestrict Host Access
Section titled “Restrict Host Access”Limit user to specific hosts:
-- Instead of '%', use specific IPCREATE USER 'querri_readonly'@'18.189.33.77'IDENTIFIED BY 'password';Use Strong Passwords
Section titled “Use Strong Passwords”-- MySQL 8.0+ password validationSET GLOBAL validate_password.policy = STRONG;SET GLOBAL validate_password.length = 16;Regular Audits
Section titled “Regular Audits”Monitor database access:
-- View current connectionsSELECT * FROM information_schema.PROCESSLISTWHERE USER = 'querri_readonly';
-- Enable general query log (for debugging only)SET GLOBAL general_log = 'ON';SET GLOBAL log_output = 'TABLE';
-- View logged queriesSELECT * FROM mysql.general_logWHERE user_host LIKE '%querri%'ORDER BY event_time DESCLIMIT 100;MySQL vs MariaDB
Section titled “MySQL vs MariaDB”The connector works with both, but note these differences:
MySQL 8.0 Features
Section titled “MySQL 8.0 Features”- Window functions
- CTEs (WITH clause)
- JSON functions
- Better optimizer
MariaDB Features
Section titled “MariaDB Features”- Sequence support
- System-versioned tables
- Different JSON implementation
Connection Pooling
Section titled “Connection Pooling”Querri uses connection pooling:
- Min connections: 1
- Max connections: 10
- Idle timeout: 5 minutes
- Reuse: Connections reused across queries
MySQL Versions
Section titled “MySQL Versions”Tested and supported:
- MySQL 8.0.x ✓
- MySQL 5.7.x ✓
- MySQL 5.6.x ✓ (limited support)
- MariaDB 10.11.x ✓
- MariaDB 10.6.x ✓
- MariaDB 10.5.x ✓
- MariaDB 10.4.x ✓
Support
Section titled “Support”MySQL Resources
Section titled “MySQL Resources”- MySQL Documentation: dev.mysql.com/doc
- MySQL Forums: forums.mysql.com
- MariaDB Documentation: mariadb.com/kb
Querri Support
Section titled “Querri Support”- Email: support@querri.com
- Documentation: /guides/connectors/