Databases & NoSQL

Mastering MySQL: An In-Depth Guide to Its Key Features and Advanced Strategies

By the Domain India teamPublished 9 min read
Knowledge base article
Contents (8 sections)

MySQL, and its close relative MariaDB, is the database behind most PHP websites, including WordPress, WooCommerce and many custom apps. Knowing a few of its features well, such as transactions, joins and indexes, is what separates a site that stays fast at 100,000 rows from one that crawls. This guide explains the features that matter in practice and the query and indexing techniques that make the biggest difference.

Key takeaways

Use the InnoDB storage engine: it gives you transactions, row-level locking and foreign keys. Learn the four join patterns you will actually use (INNER, LEFT, anti-join and the UNION workaround, because MySQL has no FULL OUTER JOIN). Index the columns you filter, join and sort on, in the right order, and check every slow query with EXPLAIN. Modern MySQL and MariaDB also support CTEs, window functions and JSON, which replace many awkward workarounds.

1. MySQL and MariaDB: what you are actually running

MySQL is an open-source relational database now developed by Oracle, with a free Community Edition. MariaDB began as a fork of MySQL and remains largely compatible for everyday SQL, but the two have drifted apart in some features and settings. Many hosting servers, including shared hosting, run MariaDB and present it as "MySQL".

For most websites the difference doesn't matter. It does matter when you import a dump made on one into the other, or use newer features. Always check the server version first:

sql
SELECT VERSION();

2. Storage engines: use InnoDB

A table's storage engine decides how its data is stored and locked. InnoDB is the default in both MySQL and MariaDB, and it is the right choice for almost every table:

FeatureInnoDBMyISAM (legacy)
Transactions (COMMIT, ROLLBACK)YesNo
LockingRow-levelWhole table
Foreign keysYesNo
Crash recoveryAutomaticTables can need repair
Recommended for new tablesYesNo

To find old MyISAM tables in a database and convert one:

sql
SELECT table_name, engine FROM information_schema.tables
WHERE table_schema = DATABASE() AND engine <> 'InnoDB';

ALTER TABLE old_table ENGINE = InnoDB;

Take a backup before converting large tables, and do it at a quiet time: the table is rebuilt.

3. Transactions and data integrity

A transaction groups several statements so they succeed or fail together. This is what "ACID" means in practice: a payment and its order row are either both saved or neither is.

sql
START TRANSACTION;
UPDATE accounts SET balance = balance - 500 WHERE id = 1;
UPDATE accounts SET balance = balance + 500 WHERE id = 2;
COMMIT;   -- or ROLLBACK; to undo both

SAVEPOINT name and ROLLBACK TO name let you undo part of a transaction. Keep transactions short: a long-running one holds locks and blocks other visitors. Use foreign keys to stop orphaned rows, and constraints such as NOT NULL, UNIQUE and CHECK (enforced in MySQL 8.0.16+ and MariaDB 10.2+) to keep bad data out at the source.

4. Joins you will actually use

Joins combine rows from two or more tables on a related column.

INNER JOIN
Only rows that match in both tables. Example: orders with their customer.
LEFT JOIN
Every row from the left table, with matches from the right, or NULL where none exists. Example: all customers, with their orders if any.
Anti-join
LEFT JOIN, then WHERE right.id IS NULL. Example: customers who have never ordered.
FULL OUTER JOIN
Not supported by MySQL or MariaDB. Combine a LEFT JOIN and a RIGHT JOIN with UNION instead.
sql
-- Customers with no orders (anti-join)
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;

-- Emulating FULL OUTER JOIN
SELECT c.id, o.id FROM customers c LEFT JOIN orders o ON o.customer_id = c.id
UNION
SELECT c.id, o.id FROM customers c RIGHT JOIN orders o ON o.customer_id = c.id;

A RIGHT JOIN is just a LEFT JOIN with the tables swapped; most people write LEFT JOINs only, which is easier to read. Always join on indexed columns, usually a primary key on one side and an indexed foreign key on the other.

5. Complex queries: grouping, CTEs and window functions

GROUP BY with aggregate functions summarises rows; HAVING filters the groups:

sql
SELECT customer_id, COUNT(*) AS orders, SUM(total) AS spent
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY customer_id
HAVING spent > 10000
ORDER BY spent DESC;

MySQL 5.7 and later enable ONLY_FULL_GROUP_BY by default (MariaDB does not), so every selected column must be grouped or aggregated. If an older app breaks on this, fix the query rather than the server; see What is SQL mode and ONLY_FULL_GROUP_BY.

Common table expressions (CTEs) and window functions are available in MySQL 8.0 and MariaDB 10.2 and later. They make reports far more readable than nested subqueries:

sql
WITH monthly AS (
  SELECT customer_id, DATE_FORMAT(created_at, '%Y-%m') AS month, SUM(total) AS spent
  FROM orders
  GROUP BY customer_id, month
)
SELECT customer_id, month, spent,
       RANK() OVER (PARTITION BY month ORDER BY spent DESC) AS rank_in_month
FROM monthly;

Both engines also store and query JSON, though their implementations differ. Keep data you filter on in normal columns and use JSON for genuinely flexible attributes.

6. Indexing strategies

An index lets the database find rows without reading the whole table. The right indexes are usually the single biggest performance gain.

  1. Find the slow queries.
    Use the slow query log on your own server, or the query monitor in your application.
  2. Look at the WHERE, JOIN and ORDER BY columns.
    These are your index candidates.
  3. Build composite indexes in the right order.
    Put columns compared with = first, then the range or sort column. An index on (customer_id, created_at) serves WHERE customer_id = 7 ORDER BY created_at; the reverse order does not.
  4. Check with EXPLAIN.
    Run EXPLAIN before the query and look at the key and rows columns. type = ALL means a full table scan.
  5. Remove what you don't use.
    Every index slows down writes and uses disk space.
sql
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
EXPLAIN SELECT * FROM orders WHERE customer_id = 7 ORDER BY created_at DESC LIMIT 20;

Queries that wrap an indexed column in a function, such as WHERE YEAR(created_at) = 2026, can't use the index. Write a range instead: WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01'. A LIKE '%term' with a leading wildcard can't use a normal index either; consider a FULLTEXT index for search.

For a step-by-step method to diagnose slow queries, see MySQL performance optimisation: diagnosing and fixing slow queries.

Back up before you change structure

ALTER TABLE, index changes and engine conversions rewrite tables. Take a backup first, and test on a copy of the database when the table is large. See how to back up a MySQL database with phpMyAdmin.

7. Security basics

  • Give each application its own database user with rights only on its own database. Never use a root or admin user in application code.
  • Use prepared statements (PDO or mysqli in PHP, parameterised queries in other languages) for every query that includes user input.
  • Keep the database port closed to the internet and connect over an SSH tunnel.

8. Running MySQL on Domain India

On Domain India shared hosting, every plan includes MariaDB/MySQL databases that you create in your control panel and manage with phpMyAdmin. phpMyAdmin shows the exact server version. On cPanel, phpMyAdmin imports files up to 50 MB. Port 3306 is closed to outside connections, so to use a desktop client, connect over an SSH tunnel as described in How to connect to the MySQL database. Jailed SSH access is available on every shared hosting plan; it is off by default, so ask support to enable it for your account. Server settings such as the slow query log or buffer sizes are managed for everyone on the server and can't be changed per account.

If you need to tune the database server itself, a VPS gives you root access to install and configure MySQL or MariaDB your own way. VPS plans are self-managed. Prices on the cards are live and exclude 18% GST.

cPanel Starter
₹125/mo + GST
  • 25 GB NVMe SSD Storage
  • 50 GB Monthly Bandwidth
  • 1 Website
  • 10 Email Accounts
See plan details
VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details
Is MariaDB the same as MySQL?

MariaDB started as a fork of MySQL and is largely compatible for everyday SQL, so most PHP applications run on either. The two have diverged in some newer features and settings, so check the server version with SELECT VERSION() before importing a dump from the other one.

Which storage engine should I use?

Use InnoDB for almost every table. It supports transactions, row-level locking, foreign keys and automatic crash recovery. MyISAM is a legacy engine without transactions and is best converted to InnoDB.

Does MySQL support FULL OUTER JOIN?

No. Neither MySQL nor MariaDB supports FULL OUTER JOIN. Combine a LEFT JOIN and a RIGHT JOIN with UNION to get the same result.

How do I know whether a query uses an index?

Put EXPLAIN in front of the query. The key column shows the index used, and the rows column estimates how many rows are read. A type of ALL means a full table scan, which usually needs an index.

Can I connect to my Domain India database from my own computer?

Port 3306 is closed to outside connections on Domain India shared servers. Connect through an SSH tunnel instead. Jailed SSH is available on every shared plan on request and is off by default, so ask support to enable it first.

Can I change MySQL server settings on shared hosting?

No. The database server on shared hosting is shared by every account, so its settings are managed for you. Improve performance with indexes and better queries, or use a VPS if you need to tune the server itself.

Ready to put this into practice? Open phpMyAdmin from your hosting services, read the SQL essentials guide, or open a support ticket if you need help with a database on your account.

Need a database for your next project?

Every Domain India shared hosting plan includes MySQL-compatible databases with phpMyAdmin.

See hosting plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Mastering MySQL: Features, Joins and Indexing | Domain India