Mysql Cheat Sheet

Basic MySQL Commands

CommandDescriptionExample
SELECTRetrieve data from a database
SELECT column1, column2 FROM table_name;
INSERTAdd new data to a table
INSERT INTO table_name (column1, column2) VALUES (value1, value2);
UPDATEModify existing data in a table
UPDATE table_name SET column1 = value1 WHERE condition;
DELETERemove data from a table
DELETE FROM table_name WHERE condition;
CREATECreate new databases or tables
CREATE TABLE table_name (column1 datatype, column2 datatype);
ALTERModify database objects
ALTER TABLE table_name ADD column_name datatype;
DROPDelete databases or tables
DROP TABLE table_name;
SHOWDisplay information about databases, tables, etc.
SHOW DATABASES; 
SHOW TABLES;
USESelect a database to work with
USE database_name;
DESCRIBE or DESCShow structure of a table
DESCRIBE table_name;
DESC table_name;

Connecting to MySQL Server

CommandDescriptionExample
mysqlBasic connection to local MySQL server
mysql -u username -p
mysql with passwordConnect with password (not recommended for production)
mysql -u username -ppassword
mysql with specific hostConnect to MySQL on a specific host
mysql -h hostname -u username -p
mysql with portConnect using a non-default port
mysql -h hostname -P 3307 -u username -p
mysql with databaseConnect and select a specific database
mysql -u username -p database_name
mysql with socketConnect using a specific socket file
mysql -u username -p --socket=/path/to/mysql.sock
mysqladminPerform administrative operations
mysqladmin -u root -p version
Connection via config fileConnect using settings in my.cnf/my.ini
mysql --defaults-file=/path/to/my.cnf
Connection timeoutSet connection timeout in seconds
mysql -u username -p --connect-timeout=10
SSL connectionConnect using SSL for security
mysql -u username -p --ssl-ca=/path/to/ca.pem

Authentication and Users

CommandDescriptionExample
CREATE USERCreate a new MySQL user
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
DROP USERDelete a MySQL user
DROP USER 'username'@'localhost';
SET PASSWORDChange a user’s password
SET PASSWORD FOR 'username'@'localhost' = PASSWORD('new_password');
ALTER USERModify user properties (MySQL 5.7+)
ALTER USER 'username'@'localhost' IDENTIFIED BY 'new_password';
RENAME USERRename a user
RENAME USER 'old_username'@'localhost' TO 'new_username'@'localhost';
GRANTGrant privileges to a user
GRANT SELECT, INSERT ON database_name.* TO 'username'@'localhost';
REVOKERemove privileges from a user
REVOKE INSERT ON database_name.* FROM 'username'@'localhost';
SHOW GRANTSShow privileges for a user
SHOW GRANTS FOR 'username'@'localhost';
FLUSH PRIVILEGESReload the privilege tables
FLUSH PRIVILEGES;
Current user infoDisplay the current user and host
SELECT USER(), CURRENT_USER();

Database Management

CommandDescriptionExample
CREATE DATABASECreate a new database
CREATE DATABASE database_name;
CREATE DATABASE with character setCreate a database with specific character set
CREATE DATABASE database_name 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;
DROP DATABASEDelete a database
DROP DATABASE database_name;
SHOW DATABASESList all databases on the server
SHOW DATABASES;
USESwitch to a specific database
USE database_name;
SHOW CREATE DATABASEShow the CREATE statement for a database
SHOW CREATE DATABASE database_name;
ALTER DATABASEModify database properties
ALTER DATABASE database_name 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;
Check size of databaseGet the total size of a database
SELECT 
  table_schema AS "Database",
  ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size (MB)"
FROM information_schema.TABLES
WHERE table_schema = "database_name"
GROUP BY table_schema;
Check database existenceCheck if a database exists before creating
CREATE DATABASE IF NOT EXISTS database_name;
Database informationGet information about databases
SELECT * FROM information_schema.SCHEMATA;

Table Management

CommandDescriptionExample
CREATE TABLECreate a new table
CREATE TABLE table_name (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100) UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE like anotherCreate a table with the same structure as another
CREATE TABLE new_table LIKE existing_table;
DROP TABLEDelete a table
DROP TABLE table_name;
TRUNCATE TABLEDelete all data from a table, but keep structure
TRUNCATE TABLE table_name;
ALTER TABLE add columnAdd a new column to a table
ALTER TABLE table_name 
ADD COLUMN column_name VARCHAR(50);
ALTER TABLE modify columnChange a column’s data type
ALTER TABLE table_name 
MODIFY COLUMN column_name VARCHAR(100);
ALTER TABLE drop columnRemove a column from a table
ALTER TABLE table_name 
DROP COLUMN column_name;
ALTER TABLE rename columnRename a column
ALTER TABLE table_name 
CHANGE COLUMN old_name new_name VARCHAR(100);
ALTER TABLE add indexAdd an index to a table
ALTER TABLE table_name 
ADD INDEX idx_name (column_name);
ALTER TABLE add foreign keyAdd a foreign key constraint
ALTER TABLE table_name 
ADD CONSTRAINT fk_name 
FOREIGN KEY (column_name) 
REFERENCES ref_table(ref_column);
RENAME TABLERename a table
RENAME TABLE old_name TO new_name;
SHOW TABLESList all tables in the current database
SHOW TABLES;
DESCRIBE or DESCShow the structure of a table
DESCRIBE table_name;
DESC table_name;
SHOW CREATE TABLEShow the CREATE statement for a table
SHOW CREATE TABLE table_name;
Table sizeGet the size of a table
SELECT 
  table_name AS "Table",
  round(((data_length + index_length) / 1024 / 1024), 2) AS "Size (MB)"
FROM information_schema.TABLES
WHERE table_schema = "database_name"
  AND table_name = "table_name";

Column Data Types

Data TypeDescriptionExample
Numeric Types
INTInteger (-2,147,483,648 to 2,147,483,647)
age INT
TINYINTVery small integer (-128 to 127)
is_active TINYINT(1)
SMALLINTSmall integer (-32,768 to 32,767)
quantity SMALLINT
MEDIUMINTMedium-sized integer (-8,388,608 to 8,388,607)
population MEDIUMINT
BIGINTLarge integer (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807)
views BIGINT
DECIMALFixed-point number (for currency or precise values)
price DECIMAL(10,2)
FLOATSingle-precision floating-point number
temperature FLOAT
DOUBLEDouble-precision floating-point number
scientific_value DOUBLE
String Types
CHARFixed-length string (0-255 chars)
state_code CHAR(2)
VARCHARVariable-length string (0-65,535 chars)
username VARCHAR(50)
TINYTEXTString up to 255 characters
short_note TINYTEXT
TEXTString up to 65,535 characters
description TEXT
MEDIUMTEXTString up to 16,777,215 characters
content MEDIUMTEXT
LONGTEXTString up to 4,294,967,295 characters
full_document LONGTEXT
ENUMString with a value chosen from a list
status ENUM('active', 'inactive', 'pending')
SETString that can have 0 or more values from a list
permissions SET('read', 'write', 'execute')
Date and Time Types
DATEDate (YYYY-MM-DD)
birth_date DATE
TIMETime (HH:MM:SS)
appointment_time TIME
DATETIMEDate and time (YYYY-MM-DD HH:MM:SS)
registered_at DATETIME
TIMESTAMPTimestamp, auto-updated on change, UTC-based
last_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
YEARYear in 4-digit format
graduation_year YEAR
Binary Types
BINARYFixed-length binary string
file_signature BINARY(16)
VARBINARYVariable-length binary string
encryption_key VARBINARY(128)
TINYBLOBBinary Large Object up to 255 bytes
small_image TINYBLOB
BLOBBinary Large Object up to 65,535 bytes
medium_image BLOB
MEDIUMBLOBBinary Large Object up to 16,777,215 bytes
large_image MEDIUMBLOB
LONGBLOBBinary Large Object up to 4,294,967,295 bytes
file_content LONGBLOB
Spatial Types
GEOMETRYAny type of geometry
shape GEOMETRY
POINTA point (X, Y)
location POINT
LINESTRINGA curve with linear interpolation
route LINESTRING
POLYGONA polygon
area POLYGON
JSON Type (MySQL 5.7+)
JSONNative JSON storage and validation
settings JSON

Inserting Data

CommandDescriptionExample
INSERT basic syntaxInsert a single row
INSERT INTO table_name (column1, column2) 
VALUES (value1, value2);
INSERT multiple rowsInsert multiple rows at once
INSERT INTO table_name (column1, column2) 
VALUES 
  (value1, value2),
  (value3, value4),
  (value5, value6);
INSERT all columnsInsert when providing values for all columns
INSERT INTO table_name 
VALUES (value1, value2, value3);
INSERT IGNOREInsert row, ignore errors (e.g., duplicates)
INSERT IGNORE INTO table_name (column1, column2) 
VALUES (value1, value2);
INSERT ... ON DUPLICATE KEY UPDATEInsert or update if duplicate key
INSERT INTO table_name (id, column1, column2) 
VALUES (1, value1, value2)
ON DUPLICATE KEY UPDATE 
  column1 = value1,
  column2 = value2;
INSERT ... SELECTInsert data from another table
INSERT INTO target_table (column1, column2)
SELECT column1, column2 
FROM source_table
WHERE condition;
REPLACEInsert a row, or replace if exists
REPLACE INTO table_name (column1, column2)
VALUES (value1, value2);
Using expressionsInsert with expressions or functions
INSERT INTO table_name (name, created_at)
VALUES ('Example', NOW());
Default valuesInsert using default values
INSERT INTO table_name (id, name, created_at)
VALUES (NULL, 'Example', DEFAULT);
Batch insertInsert multiple rows efficiently
INSERT INTO table_name (column1, column2)
VALUES 
  (value1, value2),
  (value3, value4),
  ...
  (valueN-1, valueN);

Selecting Data

CommandDescriptionExample
SELECT basic syntaxSelect specific columns from a table
SELECT column1, column2 FROM table_name;
SELECT *Select all columns
SELECT * FROM table_name;
SELECT DISTINCTSelect unique values
SELECT DISTINCT column1 FROM table_name;
SELECT with aliasRename columns in results
SELECT 
  column1 AS alias1,
  column2 AS alias2
FROM table_name;
SELECT with table aliasUse table aliases for shorter queries
SELECT t.column1, t.column2 
FROM table_name AS t;
SELECT with calculationsPerform calculations in select queries
SELECT 
  price,
  quantity,
  price * quantity AS total
FROM orders;
SELECT with functionsUse functions in selects
SELECT 
  name,
  UPPER(name) AS uppercase_name,
  LENGTH(name) AS name_length
FROM customers;
SELECT with CASEConditional logic in selects
SELECT 
  name,
  age,
  CASE 
    WHEN age < 18 THEN 'Minor'
    WHEN age >= 18 AND age < 65 THEN 'Adult'
    ELSE 'Senior'
  END AS age_category
FROM users;
SELECT with IFSimple conditional expressions
SELECT 
  name,
  IF(active = 1, 'Active', 'Inactive') AS status
FROM users;
SELECT with COALESCEReturn first non-NULL value
SELECT 
  name,
  COALESCE(phone, email, 'No Contact') AS contact
FROM customers;

Filtering Data

CommandDescriptionExample
WHERE clauseBasic filter condition
SELECT * FROM users 
WHERE age > 18;
WHERE with multiple conditionsCombine conditions with AND/OR
SELECT * FROM products 
WHERE category = 'Electronics' 
  AND price < 1000;
WHERE with INMatch against a list of values
SELECT * FROM products 
WHERE category IN ('Electronics', 'Computers', 'Accessories');
WHERE with NOT INExclude a list of values
SELECT * FROM products 
WHERE category NOT IN ('Clothing', 'Furniture');
WHERE with BETWEENMatch values in a range
SELECT * FROM products 
WHERE price BETWEEN 100 AND 500;
WHERE with LIKEPattern matching with wildcards
SELECT * FROM users 
WHERE name LIKE 'J%'; -- Names starting with J
-- % matches any number of characters
-- _ matches exactly one character
WHERE with NOT LIKEExclude pattern matches
SELECT * FROM users 
WHERE email NOT LIKE '%@gmail.com';
WHERE with REGEXPRegular expression matching
SELECT * FROM users 
WHERE name REGEXP '^[AEI]'; -- Names starting with A, E, or I
WHERE with IS NULLFind records with NULL values
SELECT * FROM users 
WHERE phone IS NULL;
WHERE with IS NOT NULLFind records with non-NULL values
SELECT * FROM users 
WHERE phone IS NOT NULL;
WHERE with subqueryFilter based on subquery results
SELECT * FROM products 
WHERE category_id IN (
  SELECT id FROM categories 
  WHERE active = 1
);
WHERE with EXISTSCheck existence of related records
SELECT * FROM customers 
WHERE EXISTS (
  SELECT 1 FROM orders 
  WHERE orders.customer_id = customers.id
);

Sorting Results

CommandDescriptionExample
ORDER BY single columnSort by one column (ascending by default)
SELECT * FROM users 
ORDER BY last_name;
ORDER BY with ASCSort in ascending order (default)
SELECT * FROM products 
ORDER BY price ASC;
ORDER BY with DESCSort in descending order
SELECT * FROM products 
ORDER BY price DESC;
ORDER BY multiple columnsSort by multiple columns
SELECT * FROM users 
ORDER BY last_name ASC, first_name ASC;
ORDER BY mixed directionsSort different columns in different directions
SELECT * FROM products 
ORDER BY category ASC, price DESC;
ORDER BY with expressionsSort by calculated values
SELECT *, price * quantity AS total 
FROM order_items 
ORDER BY total DESC;
ORDER BY with FIELDCustom sort order
SELECT * FROM products 
ORDER BY FIELD(status, 'Featured', 'Active', 'Inactive');
ORDER BY with CASEConditional sorting
SELECT * FROM orders 
ORDER BY 
  CASE 
    WHEN status = 'Processing' THEN 1
    WHEN status = 'Shipped' THEN 2
    ELSE 3
  END;
ORDER BY with NULL handlingControl how NULL values are sorted
-- NULL values first
SELECT * FROM users 
ORDER BY phone IS NOT NULL, phone ASC;

-- NULL values last
SELECT * FROM users 
ORDER BY phone IS NULL, phone ASC;
ORDER BY column positionSort by column position (avoid in production)
SELECT name, price, category FROM products 
ORDER BY 2 DESC; -- Sort by price (the 2nd column)

Limiting Results

CommandDescriptionExample
LIMIT basicLimit the number of rows returned
SELECT * FROM products 
LIMIT 10;
LIMIT with OFFSETSkip some rows and return the rest
SELECT * FROM products 
LIMIT 10 OFFSET 20; -- Skip 20 rows, return next 10
LIMIT shorthandAlternative syntax with offset first
SELECT * FROM products 
LIMIT 20, 10; -- Skip 20 rows, return next 10
LIMIT for paginationGet a specific page of results
-- For page 3 with 10 items per page
SELECT * FROM products 
LIMIT 10 OFFSET 20; -- (page - 1) * items_per_page
LIMIT with ORDER BYGet top N rows by a criteria
-- Top 5 most expensive products
SELECT * FROM products 
ORDER BY price DESC 
LIMIT 5;
LIMIT in subqueryUse limits in subqueries
SELECT * FROM orders 
WHERE customer_id IN (
  SELECT id FROM customers 
  ORDER BY total_spend DESC 
  LIMIT 10
);
LIMIT random rowGet a random row
SELECT * FROM products 
ORDER BY RAND() 
LIMIT 1;
LIMIT with aggregationsFind top values after grouping
-- Top 3 categories by total sales
SELECT category, SUM(price * quantity) AS total_sales 
FROM order_items
JOIN products ON order_items.product_id = products.id
GROUP BY category
ORDER BY total_sales DESC
LIMIT 3;
LIMIT with variablesUsing variables for dynamic limits
-- Using prepared statements
PREPARE stmt FROM 'SELECT * FROM products LIMIT ?';
SET @limit = 5;
EXECUTE stmt USING @limit;
DEALLOCATE PREPARE stmt;
No LIMIT clauseReturn all matching rows (use with caution)
SELECT * FROM products; -- No limit, returns all rows

Updating Data

CommandDescriptionExample
UPDATE basic syntaxUpdate one or more columns in one or more rows
UPDATE table_name
SET column1 = value1, column2 = value2
WHERE condition;
UPDATE all rowsUpdate all rows (be careful!)
-- Update all rows (use with caution)
UPDATE products
SET in_stock = 0;
UPDATE with expressionsUpdate using expressions or calculations
UPDATE products
SET price = price * 1.1 -- Increase price by 10%
WHERE category = 'Electronics';
UPDATE with functionsUpdate using functions
UPDATE users
SET last_login = NOW(),
    login_count = login_count + 1
WHERE id = 123;
UPDATE with CASEConditional updates
UPDATE orders
SET status = 
  CASE 
    WHEN payment_received = 1 AND shipped = 0 THEN 'Paid'
    WHEN payment_received = 1 AND shipped = 1 THEN 'Completed'
    ELSE 'Pending'
  END;
UPDATE with LIMITLimit the number of rows to update
UPDATE users
SET status = 'inactive'
WHERE last_login < DATE_SUB(NOW(), INTERVAL 1 YEAR)
LIMIT 100;
UPDATE with ORDER BYUpdate rows in a specific order
UPDATE products
SET featured = 1
WHERE category = 'Electronics'
ORDER BY price DESC
LIMIT 5;
UPDATE with subqueryUpdate based on data from other tables
UPDATE employees
SET salary = salary * 1.1
WHERE department_id IN (
  SELECT id FROM departments WHERE performance_rating > 8
);
UPDATE with JOINUpdate data based on joined tables
UPDATE orders o
JOIN customers c ON o.customer_id = c.id
SET o.discount = 0.1
WHERE c.loyalty_points > 1000;
UPDATE IGNOREContinue update even if errors occur
UPDATE IGNORE users
SET email = LOWER(email),
    username = LOWER(username);

Deleting Data

CommandDescriptionExample
DELETE basic syntaxDelete rows from a table
DELETE FROM table_name
WHERE condition;
DELETE all rowsDelete all rows (be very careful!)
-- Delete all rows (use with extreme caution)
DELETE FROM temporary_logs;
DELETE with LIMITLimit the number of rows to delete
DELETE FROM logs
WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR)
LIMIT 1000;
DELETE with ORDER BYDelete rows in a specific order
DELETE FROM logs
WHERE type = 'error'
ORDER BY created_at
LIMIT 100;
DELETE with subqueryDelete based on a subquery
DELETE FROM cart_items
WHERE user_id IN (
  SELECT id FROM users
  WHERE last_activity < DATE_SUB(NOW(), INTERVAL 30 DAY)
);
DELETE with multiple tablesDelete from multiple tables at once
DELETE c, o
FROM customers c
JOIN orders o ON c.id = o.customer_id
WHERE c.active = 0;
TRUNCATE TABLEDelete all rows (faster than DELETE, resets AUTO_INCREMENT)
TRUNCATE TABLE logs;
DELETE vs TRUNCATEDifferences between DELETE and TRUNCATE
-- DELETE: one by one, can be rolled back, preserves AUTO_INCREMENT
DELETE FROM table_name;

-- TRUNCATE: drops and recreates table, faster, resets AUTO_INCREMENT
TRUNCATE TABLE table_name;
Soft deleteMark records as deleted instead of actual deletion
-- Instead of deleting the records
UPDATE users
SET deleted_at = NOW(), active = 0
WHERE id = 123;
DELETE IGNOREContinue delete operation even if errors occur
DELETE IGNORE FROM products
WHERE category_id = 5;

Joins

CommandDescriptionExample
INNER JOINReturn rows when there is a match in both tables
SELECT o.id, c.name
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id;
LEFT JOINReturn all rows from left table and matched rows from right table
SELECT c.name, o.id
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
RIGHT JOINReturn all rows from right table and matched rows from left table
SELECT o.id, p.name
FROM orders o
RIGHT JOIN products p ON o.product_id = p.id;
FULL OUTER JOIN (emulated)Return rows when there is a match in either table (MySQL doesn't directly support FULL JOIN)
-- Emulating FULL JOIN in MySQL
SELECT c.name, o.id
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
UNION
SELECT c.name, o.id
FROM customers c
RIGHT JOIN orders o ON c.id = o.customer_id
WHERE c.id IS NULL;
CROSS JOINReturn the Cartesian product (all combinations of rows)
SELECT c.name, p.name
FROM customers c
CROSS JOIN products p;
Self JoinJoin a table to itself
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.id;
Multiple JoinsJoin more than two tables
SELECT o.id, c.name, p.name, p.price
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id;
Join with conditionsAdd WHERE clauses to filter joined data
SELECT o.id, c.name
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE o.status = 'shipped'
AND c.country = 'USA';
Join with USINGJoin tables with identically named columns
SELECT o.id, c.name
FROM orders o
JOIN customers c USING (customer_id);
Join with NATURAL JOINJoin based on all columns with same name (use with caution)
SELECT o.id, c.name
FROM orders o
NATURAL JOIN customers c;

Grouping and Aggregating

CommandDescriptionExample
GROUP BY basicGroup rows that have the same values
SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category;
COUNT()Count the number of rows or non-NULL values
-- Count all rows
SELECT COUNT(*) FROM orders;

-- Count non-NULL values in a column
SELECT COUNT(phone) FROM customers;
SUM()Calculate the sum of values
SELECT category, SUM(price) AS total_value
FROM products
GROUP BY category;
AVG()Calculate the average of values
SELECT category, AVG(price) AS average_price
FROM products
GROUP BY category;
MIN()Find the minimum value
SELECT category, MIN(price) AS lowest_price
FROM products
GROUP BY category;
MAX()Find the maximum value
SELECT category, MAX(price) AS highest_price
FROM products
GROUP BY category;
GROUP_CONCAT()Concatenate values from grouped rows
SELECT category, GROUP_CONCAT(name SEPARATOR ', ') AS products
FROM products
GROUP BY category;
HAVING clauseFilter groups based on aggregate functions
SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category
HAVING product_count > 5;
WITH ROLLUPInclude summary rows
SELECT category, subcategory, SUM(price) AS total
FROM products
GROUP BY category, subcategory WITH ROLLUP;
Multiple aggregationsUse multiple aggregate functions together
SELECT category,
  COUNT(*) AS count,
  MIN(price) AS min_price,
  MAX(price) AS max_price,
  AVG(price) AS avg_price,
  SUM(price) AS total_value
FROM products
GROUP BY category;
Group by multiple columnsGroup by more than one column
SELECT category, manufacturer, COUNT(*) AS product_count
FROM products
GROUP BY category, manufacturer
ORDER BY category, product_count DESC;
Group by with joinGroup results from joined tables
SELECT c.country, COUNT(o.id) AS order_count
FROM customers c
JOIN orders o ON c.id = o.customer_id
GROUP BY c.country
ORDER BY order_count DESC;

Subqueries

CommandDescriptionExample
Subquery in WHEREUse a subquery in WHERE clause
SELECT name
FROM products
WHERE category_id IN (
  SELECT id FROM categories
  WHERE parent_id = 5
);
Subquery with comparisonCompare to a single value from subquery
SELECT name, price
FROM products
WHERE price > (
  SELECT AVG(price) FROM products
);
Subquery with INCheck if a value is in the result set
SELECT *
FROM customers
WHERE id IN (
  SELECT DISTINCT customer_id
  FROM orders
  WHERE total > 1000
);
Subquery with NOT INCheck if a value is not in the result set
SELECT *
FROM products
WHERE id NOT IN (
  SELECT product_id
  FROM order_items
);
Subquery with EXISTSCheck if the subquery returns any rows
SELECT *
FROM customers c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.id
  AND o.created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
);
Subquery with NOT EXISTSCheck if the subquery returns no rows
SELECT *
FROM products p
WHERE NOT EXISTS (
  SELECT 1
  FROM order_items oi
  WHERE oi.product_id = p.id
);
Subquery in SELECTUse a subquery in SELECT statement
SELECT 
  name,
  price,
  (SELECT AVG(price) FROM products) AS avg_price,
  price - (SELECT AVG(price) FROM products) AS diff_from_avg
FROM products;
Correlated subquerySubquery that references the outer query
SELECT p1.name, p1.price
FROM products p1
WHERE p1.price > (
  SELECT AVG(p2.price)
  FROM products p2
  WHERE p2.category_id = p1.category_id
);
Subquery in FROMUse a subquery as a derived table
SELECT category, avg_price
FROM (
  SELECT category, AVG(price) AS avg_price
  FROM products
  GROUP BY category
) AS category_stats
WHERE avg_price > 100;
Subquery with ALLCompare with all values returned by subquery
SELECT name, price
FROM products
WHERE price > ALL (
  SELECT price
  FROM products
  WHERE category_id = 3
);
Subquery with ANYCompare with any value returned by subquery
SELECT name, price
FROM products
WHERE price > ANY (
  SELECT price
  FROM products
  WHERE category_id = 3
);
Scalar subquerySubquery that returns exactly one value
SELECT name,
  price,
  (SELECT MAX(price) FROM products) AS max_price,
  price / (SELECT MAX(price) FROM products) * 100 AS percentage_of_max
FROM products;

Views

CommandDescriptionExample
CREATE VIEWCreate a virtual table based on a SELECT query
CREATE VIEW product_details AS
SELECT 
  p.id, 
  p.name, 
  p.price, 
  c.name AS category
FROM products p
JOIN categories c ON p.category_id = c.id;
CREATE OR REPLACE VIEWCreate a view or replace it if it exists
CREATE OR REPLACE VIEW high_value_customers AS
SELECT 
  id, 
  name, 
  email, 
  total_orders
FROM customers
WHERE total_orders > 10;
DROP VIEWDelete a view
DROP VIEW product_details;
DROP VIEW IF EXISTSDelete a view if it exists
DROP VIEW IF EXISTS product_details;
SHOW CREATE VIEWShow the CREATE VIEW statement
SHOW CREATE VIEW product_details;
ALTER VIEWModify a view definition
ALTER VIEW product_details AS
SELECT 
  p.id, 
  p.name, 
  p.price, 
  p.description,
  c.name AS category
FROM products p
JOIN categories c ON p.category_id = c.id;
Selecting from a viewQuery a view just like a regular table
SELECT * FROM product_details
WHERE price > 100;
View with WITH CHECK OPTIONPrevents updates that would make rows not visible through the view
CREATE VIEW active_products AS
SELECT id, name, price, status
FROM products
WHERE status = 'active'
WITH CHECK OPTION;
Updatable viewView that allows UPDATE, INSERT, DELETE operations
CREATE VIEW basic_product_info AS
SELECT id, name, price, category_id
FROM products;
View with join (read-only)Views with joins are generally read-only
CREATE VIEW order_summary AS
SELECT 
  o.id AS order_id,
  c.name AS customer_name,
  o.total AS order_total,
  o.created_at AS order_date
FROM orders o
JOIN customers c ON o.customer_id = c.id;
View with aggregationCreate a view with aggregate functions
CREATE VIEW category_stats AS
SELECT 
  category_id,
  COUNT(*) AS product_count,
  AVG(price) AS avg_price,
  MIN(price) AS min_price,
  MAX(price) AS max_price
FROM products
GROUP BY category_id;
Using views for securityLimit access to specific columns or rows
CREATE VIEW public_customer_info AS
SELECT id, name, city, country
FROM customers;

-- Then grant access to this view instead of the base table
GRANT SELECT ON public_customer_info TO 'app_user'@'localhost';

Indexes

CommandDescriptionExample
CREATE INDEXCreate an index on a table column
CREATE INDEX idx_last_name ON users(last_name);
CREATE UNIQUE INDEXCreate an index that enforces uniqueness
CREATE UNIQUE INDEX idx_email ON users(email);
Composite indexCreate an index on multiple columns
CREATE INDEX idx_name_email ON users(last_name, first_name, email);
Primary key indexCreate a primary key (automatically indexed)
CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(100)
);
Foreign key indexCreate a foreign key (best to index it)
CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT,
  total DECIMAL(10,2),
  INDEX idx_user_id (user_id),
  FOREIGN KEY (user_id) REFERENCES users(id)
);
SHOW INDEXESList all indexes on a table
SHOW INDEXES FROM table_name;
DROP INDEXRemove an index
DROP INDEX idx_name ON table_name;
ALTER TABLE to add indexAdd an index using ALTER TABLE
ALTER TABLE users
ADD INDEX idx_created_at (created_at);
Partial indexIndex only part of a string column
CREATE INDEX idx_name_prefix ON products(name(10));
Descending indexCreate an index in descending order (MySQL 8.0+)
CREATE INDEX idx_created_desc ON users(created_at DESC);
Fulltext indexCreate an index for full-text search
CREATE FULLTEXT INDEX idx_content ON articles(title, content);
Spatial indexCreate an index for spatial data
CREATE SPATIAL INDEX idx_location ON stores(location);
Invisible indexCreate an index that isn't used by the optimizer (MySQL 8.0+)
CREATE INDEX idx_test ON users(test_column) INVISIBLE;
Functional indexCreate an index on an expression (MySQL 8.0+)
CREATE INDEX idx_upper_email ON users((UPPER(email)));

Transactions

CommandDescriptionExample
START TRANSACTIONBegin a new transaction
START TRANSACTION;
BEGINBegin a new transaction (alternative syntax)
BEGIN;
COMMITSave changes and end transaction
COMMIT;
ROLLBACKDiscard changes and end transaction
ROLLBACK;
SAVEPOINTCreate a point to which you can roll back
SAVEPOINT my_savepoint;
ROLLBACK TO SAVEPOINTRoll back to a specific savepoint
ROLLBACK TO SAVEPOINT my_savepoint;
RELEASE SAVEPOINTDelete a savepoint
RELEASE SAVEPOINT my_savepoint;
SET TRANSACTIONSet transaction characteristics
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Complete transaction exampleFull transaction with error handling
START TRANSACTION;

INSERT INTO orders (customer_id, total)
VALUES (123, 456.78);

-- Get the new order ID
SET @order_id = LAST_INSERT_ID();

INSERT INTO order_items (order_id, product_id, quantity, price)
VALUES 
  (@order_id, 1, 2, 100.00),
  (@order_id, 2, 1, 256.78);

-- If everything is OK, commit the transaction
COMMIT;

-- On error, you would do:
-- ROLLBACK;
Setting isolation levelChange the transaction isolation level
-- Available levels:
-- READ UNCOMMITTED
-- READ COMMITTED
-- REPEATABLE READ (default in MySQL)
-- SERIALIZABLE

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Read-only transactionSet a transaction to read-only mode
START TRANSACTION READ ONLY;
Check autocommit statusSee if autocommit is enabled
SELECT @@autocommit;
Disable autocommitTurn off automatic commits
SET autocommit = 0;
Enable autocommitTurn on automatic commits
SET autocommit = 1;

Stored Procedures and Functions

CommandDescriptionExample
CREATE PROCEDURECreate a stored procedure
DELIMITER //

CREATE PROCEDURE get_customers(IN country_filter VARCHAR(50))
BEGIN
  SELECT * FROM customers
  WHERE country = country_filter;
END //

DELIMITER ;
CALLExecute a stored procedure
CALL get_customers('USA');
DROP PROCEDUREDelete a stored procedure
DROP PROCEDURE get_customers;
CREATE FUNCTIONCreate a stored function
DELIMITER //

CREATE FUNCTION calculate_discount(
  price DECIMAL(10,2),
  discount_percent INT
) 
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
  DECLARE discounted_price DECIMAL(10,2);
  SET discounted_price = price * (1 - discount_percent/100);
  RETURN discounted_price;
END //

DELIMITER ;
Using a stored functionUse a function in SQL queries
SELECT 
  name,
  price,
  calculate_discount(price, 10) AS discounted_price
FROM products;
DROP FUNCTIONDelete a stored function
DROP FUNCTION calculate_discount;
Procedure with OUT parameterCreate a procedure that returns a value
DELIMITER //

CREATE PROCEDURE get_product_count(
  IN category_id INT,
  OUT product_count INT
)
BEGIN
  SELECT COUNT(*) INTO product_count
  FROM products
  WHERE products.category_id = category_id;
END //

DELIMITER ;
Using OUT parametersCall a procedure and get the OUT value
SET @count = 0;
CALL get_product_count(5, @count);
SELECT @count;
Procedure with INOUT parameterCreate a procedure with an INOUT parameter
DELIMITER //

CREATE PROCEDURE double_value(
  INOUT value INT
)
BEGIN
  SET value = value * 2;
END //

DELIMITER ;
Using INOUT parametersCall a procedure with an INOUT parameter
SET @val = 5;
CALL double_value(@val);
SELECT @val; -- Will return 10
Procedure with error handlingCreate a procedure with error handling
DELIMITER //

CREATE PROCEDURE insert_product(
  IN p_name VARCHAR(100),
  IN p_price DECIMAL(10,2)
)
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
    SELECT 'Error occurred. Transaction rolled back.' AS message;
  END;
  
  START TRANSACTION;
    INSERT INTO products (name, price)
    VALUES (p_name, p_price);
  COMMIT;
  
  SELECT 'Product added successfully.' AS message;
END //

DELIMITER ;
Show procedures/functionsList stored procedures or functions
-- View all procedures in the current database
SHOW PROCEDURE STATUS WHERE Db = DATABASE();

-- View all functions in the current database
SHOW FUNCTION STATUS WHERE Db = DATABASE();
View procedure/function codeSee the source code of a procedure or function
-- View procedure code
SHOW CREATE PROCEDURE procedure_name;

-- View function code
SHOW CREATE FUNCTION function_name;
Using conditionalsUse IF-ELSE statements in a procedure
DELIMITER //

CREATE PROCEDURE apply_discount(
  IN order_id INT
)
BEGIN
  DECLARE total DECIMAL(10,2);
  
  SELECT total_amount INTO total
  FROM orders
  WHERE id = order_id;
  
  IF total > 1000 THEN
    UPDATE orders SET discount = 0.15 WHERE id = order_id;
  ELSEIF total > 500 THEN
    UPDATE orders SET discount = 0.1 WHERE id = order_id;
  ELSE
    UPDATE orders SET discount = 0.05 WHERE id = order_id;
  END IF;
END //

DELIMITER ;

Triggers

CommandDescriptionExample
CREATE TRIGGERCreate a trigger that runs before or after an event
DELIMITER //

CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
  UPDATE customers
  SET order_count = order_count + 1
  WHERE id = NEW.customer_id;
END //

DELIMITER ;
BEFORE INSERT triggerRun before a new row is inserted
DELIMITER //

CREATE TRIGGER before_user_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
  SET NEW.email = LOWER(NEW.email);
  SET NEW.created_at = NOW();
END //

DELIMITER ;
AFTER INSERT triggerRun after a new row is inserted
DELIMITER //

CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
  INSERT INTO order_log (order_id, action, timestamp)
  VALUES (NEW.id, 'Order created', NOW());
END //

DELIMITER ;
BEFORE UPDATE triggerRun before a row is updated
DELIMITER //

CREATE TRIGGER before_product_update
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
  SET NEW.updated_at = NOW();
  
  IF NEW.price != OLD.price THEN
    INSERT INTO price_history (product_id, old_price, new_price, changed_at)
    VALUES (OLD.id, OLD.price, NEW.price, NOW());
  END IF;
END //

DELIMITER ;
AFTER UPDATE triggerRun after a row is updated
DELIMITER //

CREATE TRIGGER after_status_update
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
  IF NEW.status != OLD.status THEN
    INSERT INTO order_status_log (order_id, old_status, new_status, changed_at)
    VALUES (OLD.id, OLD.status, NEW.status, NOW());
  END IF;
END //

DELIMITER ;
BEFORE DELETE triggerRun before a row is deleted
DELIMITER //

CREATE TRIGGER before_user_delete
BEFORE DELETE ON users
FOR EACH ROW
BEGIN
  INSERT INTO deleted_users (id, name, email, deleted_at)
  VALUES (OLD.id, OLD.name, OLD.email, NOW());
END //

DELIMITER ;
AFTER DELETE triggerRun after a row is deleted
DELIMITER //

CREATE TRIGGER after_product_delete
AFTER DELETE ON products
FOR EACH ROW
BEGIN
  DELETE FROM product_tags WHERE product_id = OLD.id;
END //

DELIMITER ;
DROP TRIGGERDelete a trigger
DROP TRIGGER before_user_insert;
SHOW TRIGGERSList all triggers
SHOW TRIGGERS;

-- Or for specific database/table
SHOW TRIGGERS WHERE `Table` = 'users';
Combined triggersCreate triggers for multiple events
-- You need separate triggers for each event
-- This example shows how to create two related triggers

DELIMITER //

CREATE TRIGGER before_inventory_insert
BEFORE INSERT ON inventory
FOR EACH ROW
BEGIN
  SET NEW.last_updated = NOW();
END //

CREATE TRIGGER before_inventory_update
BEFORE UPDATE ON inventory
FOR EACH ROW
BEGIN
  SET NEW.last_updated = NOW();
END //

DELIMITER ;
Trigger with conditionsCreate a trigger that executes conditionally
DELIMITER //

CREATE TRIGGER check_minimum_price
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
  IF NEW.price < 0 THEN
    SET NEW.price = 0;
  END IF;
END //

DELIMITER ;
Trigger with error handlingCreate a trigger that signals an error
DELIMITER //

CREATE TRIGGER prevent_price_decrease
BEFORE UPDATE ON products
FOR EACH ROW
BEGIN
  IF NEW.price < OLD.price THEN
    SIGNAL SQLSTATE '45000' 
    SET MESSAGE_TEXT = 'Price cannot be decreased';
  END IF;
END //

DELIMITER ;

Backup and Restore

CommandDescriptionExample
mysqldump basicBackup a database to a SQL file
mysqldump -u username -p database_name > backup.sql
mysqldump multiple databasesBackup multiple databases
mysqldump -u username -p --databases db1 db2 > backup.sql
mysqldump all databasesBackup all databases
mysqldump -u username -p --all-databases > backup.sql
mysqldump specific tablesBackup specific tables in a database
mysqldump -u username -p database_name table1 table2 > backup.sql
mysqldump with optionsBackup with specific options
mysqldump -u username -p --single-transaction --routines --triggers database_name > backup.sql
mysqldump exclude tablesBackup excluding specific tables
mysqldump -u username -p database_name --ignore-table=database_name.table_to_ignore > backup.sql
mysqldump compress outputCompress the backup file
mysqldump -u username -p database_name | gzip > backup.sql.gz
Restore from mysqldumpRestore a database from a SQL file
mysql -u username -p database_name < backup.sql
Restore compressed backupRestore from a compressed SQL file
gunzip < backup.sql.gz | mysql -u username -p database_name
mysqlpumpEnhanced backup utility (MySQL 5.7+)
mysqlpump -u username -p --parallel-schemas=4 database_name > backup.sql
mysqldump with progressShow progress during backup
mysqldump -u username -p --verbose database_name > backup.sql
Binary log backupBackup binary logs for point-in-time recovery
mysqlbinlog binlog.000001 binlog.000002 > binlog_backup.sql
Physical backup with MySQL Enterprise BackupCommercial hot backup solution
mysqlbackup --user=username --password=password --backup-dir=/backup backup
Physical backup with Percona XtraBackupOpen-source hot backup solution
xtrabackup --backup --target-dir=/backup
Restore with Percona XtraBackupRestore from XtraBackup
xtrabackup --prepare --target-dir=/backup
xtrabackup --copy-back --target-dir=/backup
Backup with encryptionCreate an encrypted backup
mysqldump -u username -p database_name | openssl enc -aes-256-cbc -salt -out backup.sql.enc
Scheduled backup with cronSetup automatic backups
# Add to crontab (crontab -e):
0 2 * * * mysqldump -u username -p"password" database_name | gzip > /backup/db_$(date +\%Y\%m\%d).sql.gz

Importing and Exporting Data

CommandDescriptionExample
LOAD DATA INFILEImport data from a CSV/text file
LOAD DATA INFILE '/path/to/data.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS; -- Skip header row
LOAD DATA LOCAL INFILEImport from a file on the client side
LOAD DATA LOCAL INFILE '/path/to/local/data.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
SELECT INTO OUTFILEExport data to a CSV/text file
SELECT * FROM table_name
INTO OUTFILE '/path/to/export.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
mysqldump for exportExport data to a SQL file
mysqldump -u username -p database_name table_name > table_export.sql
mysqlimportImport data using the command-line tool
mysqlimport -u username -p --fields-terminated-by=',' \
  --lines-terminated-by='\n' database_name /path/to/data.csv
Export to JSONExport query results as JSON
SELECT JSON_OBJECT(
  'id', id,
  'name', name,
  'email', email
) AS json_data
FROM users
INTO OUTFILE '/path/to/users.json';
Import from JSONImport JSON data
-- Create a table for JSON data
CREATE TABLE json_import (data JSON);

-- Load JSON file
LOAD DATA INFILE '/path/to/data.json'
INTO TABLE json_import;
mysqldump with tab formatExport as tab-delimited files
mysqldump -u username -p --tab=/path/to/directory database_name
Export with column headersInclude headers in the export
-- First, output column headers
SELECT 'id', 'name', 'email' 
UNION ALL
SELECT id, name, email FROM users
INTO OUTFILE '/path/to/users_with_headers.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
Import XMLImport data from XML format
-- Using LOAD XML (MySQL 5.5+)
LOAD XML INFILE '/path/to/data.xml'
INTO TABLE table_name
ROWS IDENTIFIED BY 'row';
Export XMLExport data in XML format
-- Select with XML functions
SELECT
  CONCAT(
    '<user>',
    '<id>', id, '</id>',
    '<name>', name, '</name>',
    '<email>', email, '</email>',
    '</user>'
  ) AS xml_data
FROM users
INTO OUTFILE '/path/to/users.xml';
Export with mysqldump and --xmlExport database or table in XML format
mysqldump -u username -p --xml database_name table_name > table_export.xml
Import and transform dataImport data with transformations
LOAD DATA INFILE '/path/to/data.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(@col1, @col2, @col3)
SET 
  id = @col1,
  name = UPPER(@col2),
  email = LOWER(@col3),
  created_at = NOW();
Import from ExcelImport data from Excel
-- Save Excel as CSV first, then:
LOAD DATA INFILE '/path/to/excel_export.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n' -- Excel uses CRLF
IGNORE 1 ROWS;
sql_mode for importingSet SQL mode for importing data
-- Relax constraints during import
SET SESSION sql_mode='';

-- Load data
LOAD DATA INFILE '/path/to/data.csv'
INTO TABLE table_name
FIELDS TERMINATED BY ',';

User Privileges and Permissions

CommandDescriptionExample
GRANT basicGrant privileges to a user
GRANT SELECT, INSERT, UPDATE ON database_name.* TO 'username'@'localhost';
GRANT all privilegesGrant all privileges on a database
GRANT ALL PRIVILEGES ON database_name.* TO 'username'@'localhost';
GRANT with IDENTIFIED BYCreate user and grant privileges
GRANT ALL PRIVILEGES ON database_name.* 
TO 'username'@'localhost' IDENTIFIED BY 'password';
GRANT on specific tableGrant privileges on a specific table
GRANT SELECT, UPDATE ON database_name.table_name TO 'username'@'localhost';
GRANT on specific columnsGrant privileges on specific columns
GRANT SELECT (id, name), UPDATE (name) 
ON database_name.table_name TO 'username'@'localhost';
GRANT with GRANT OPTIONAllow user to grant their privileges to others
GRANT SELECT ON database_name.* 
TO 'username'@'localhost' WITH GRANT OPTION;
REVOKE basicRemove privileges from a user
REVOKE INSERT ON database_name.* FROM 'username'@'localhost';
REVOKE all privilegesRemove all privileges
REVOKE ALL PRIVILEGES ON database_name.* FROM 'username'@'localhost';
REVOKE grant optionRemove the ability to grant privileges
REVOKE GRANT OPTION ON database_name.* FROM 'username'@'localhost';
SHOW GRANTSView privileges of a user
SHOW GRANTS FOR 'username'@'localhost';
Global privilegesGrant server-level privileges
GRANT CREATE USER ON *.* TO 'admin'@'localhost';
Common privilege typesMost frequently used privilege types
-- Data privileges
GRANT SELECT, INSERT, UPDATE, DELETE ON db.* TO 'user'@'localhost';

-- Structure privileges
GRANT CREATE, ALTER, DROP ON db.* TO 'user'@'localhost';

-- Admin privileges
GRANT CREATE USER, RELOAD, PROCESS ON *.* TO 'admin'@'localhost';
User roles (MySQL 8.0+)Create and manage roles
-- Create role
CREATE ROLE 'app_read', 'app_write';

-- Grant privileges to role
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';

-- Grant role to users
GRANT 'app_read', 'app_write' TO 'app_user'@'localhost';

-- Set default role
SET DEFAULT ROLE 'app_read', 'app_write' TO 'app_user'@'localhost';
Activate roleActivate a granted role (MySQL 8.0+)
SET ROLE 'app_read';
View user informationSee users and their attributes
SELECT User, Host FROM mysql.user;
Limit resource usageSet user resource limits
CREATE USER 'username'@'localhost'
WITH MAX_QUERIES_PER_HOUR 1000
     MAX_UPDATES_PER_HOUR 500
     MAX_CONNECTIONS_PER_HOUR 200
     MAX_USER_CONNECTIONS 10;

Managing Connections and Sessions

CommandDescriptionExample
SHOW PROCESSLISTDisplay list of active connections
SHOW PROCESSLIST;
SHOW FULL PROCESSLISTDisplay complete active connections with full query text
SHOW FULL PROCESSLIST;
KILL CONNECTIONTerminate a specific connection
KILL CONNECTION 1234;
KILL QUERYTerminate a specific query without killing the connection
KILL QUERY 1234;
SET SESSIONSet a variable for the current session only
SET SESSION sort_buffer_size = 10485760;
SHOW SESSION VARIABLESDisplay all session variables
SHOW SESSION VARIABLES;
SHOW SESSION VARIABLES LIKEDisplay session variables matching a pattern
SHOW SESSION VARIABLES LIKE 'max%';
SHOW SESSION STATUSDisplay session status information
SHOW SESSION STATUS;
SET SESSION SQL_MODEChange SQL mode for current session
SET SESSION SQL_MODE = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES';
SELECT CONNECTION_ID()Get the connection ID for the current connection
SELECT CONNECTION_ID();
GET LOCKGet named lock (for coordination between sessions)
SELECT GET_LOCK('my_lock', 10);
RELEASE LOCKRelease a named lock
SELECT RELEASE_LOCK('my_lock');
IS_FREE_LOCKCheck if a named lock is free
SELECT IS_FREE_LOCK('my_lock');
SHOW ENGINE INNODB STATUSDisplay detailed InnoDB status including transactions and locks
SHOW ENGINE INNODB STATUS;
SET wait_timeoutSet the timeout for interactive connections
SET SESSION wait_timeout = 28800;
SET interactive_timeoutSet the timeout for interactive connections
SET SESSION interactive_timeout = 28800;

Configuration Files and Server Settings

ConfigurationDescriptionExample
Main configuration filePrimary MySQL configuration file locations
Linux: /etc/mysql/my.cnf or /etc/my.cnf
Windows: C:\ProgramData\MySQL\MySQL Server X.Y\my.ini
macOS: /usr/local/mysql/etc/my.cnf
SHOW VARIABLESDisplay all MySQL server variables
SHOW VARIABLES;
SHOW VARIABLES LIKEDisplay server variables matching a pattern
SHOW VARIABLES LIKE 'innodb%';
SHOW GLOBAL VARIABLESDisplay global server variables
SHOW GLOBAL VARIABLES;
SET GLOBALModify global server variables (requires privileges)
SET GLOBAL max_connections = 500;
SET PERSIST (MySQL 8.0+)Set variable persistently (survives restart)
SET PERSIST max_connections = 500;
SHOW STATUSDisplay server status variables
SHOW STATUS;
SHOW GLOBAL STATUSDisplay global status information
SHOW GLOBAL STATUS;
Common my.cnf sectionsMain configuration file sections
[client] - Client settings
[mysqld] - Server settings
[mysqldump] - Backup tool settings
[mysql] - MySQL client settings
InnoDB configurationCommon InnoDB settings
[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
Performance settingsCommon performance-related parameters
[mysqld]
max_connections = 500
table_open_cache = 4000
query_cache_size = 0 # Disabled in MySQL 8.0+
max_allowed_packet = 64M
Character set configurationConfigure default character sets
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

[client]
default-character-set = utf8mb4
Binary log settingsConfigure binary logging
[mysqld]
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 14
max_binlog_size = 100M
Logging settingsConfigure error and general logs
[mysqld]
log_error = /var/log/mysql/error.log
general_log = 0
general_log_file = /var/log/mysql/mysql.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
mysqld --verbose --helpDisplay all server options and default values
mysqld --verbose --help
RESET PERSIST (MySQL 8.0+)Remove a persisted variable setting
RESET PERSIST max_connections;

Performance Optimization

Command/TechniqueDescriptionExample
EXPLAINAnalyze a query's execution plan
EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';
EXPLAIN FORMAT=JSONDetailed execution plan in JSON format
EXPLAIN FORMAT=JSON SELECT * FROM users u 
JOIN orders o ON u.id = o.user_id WHERE u.status = 'active';
EXPLAIN ANALYZE (MySQL 8.0+)Get execution plan with actual performance metrics
EXPLAIN ANALYZE SELECT * FROM users 
JOIN orders ON users.id = orders.user_id 
WHERE users.created_at > '2022-01-01';
SHOW INDEXDisplay indexes for a table
SHOW INDEX FROM users;
CREATE INDEXCreate an index on columns
CREATE INDEX idx_email ON users(email);
SHOW PROFILEGet detailed execution information for a query
SET profiling = 1;
-- Run your query
SELECT * FROM large_table WHERE complex_condition;
-- Get the profile
SHOW PROFILES;
SHOW PROFILE FOR QUERY 1;
SHOW STATUS for query cacheCheck query cache status (pre-MySQL 8.0)
SHOW STATUS LIKE 'Qcache%';
ANALYZE TABLEUpdate index statistics for better query plans
ANALYZE TABLE users;
OPTIMIZE TABLEDefragment a table to improve performance
OPTIMIZE TABLE orders;
Covering indexesCreate indexes that include all columns needed by a query
CREATE INDEX idx_user_email_status ON users(email, status);
Compound indexesCreate indexes on multiple columns for better filtering
CREATE INDEX idx_last_first_email ON users(last_name, first_name, email);
LIMIT optimizationUse LIMIT for large result sets
-- Instead of selecting all rows
SELECT * FROM large_table LIMIT 1000;
Avoid SELECT *Select only needed columns to reduce I/O
-- Instead of:
SELECT * FROM users;
-- Use:
SELECT id, name, email FROM users;
Join optimizationEnsure JOINed columns are indexed
CREATE INDEX idx_user_id ON orders(user_id);
PartitioningDivide large tables into manageable pieces
CREATE TABLE sales (
  id INT NOT NULL,
  sale_date DATE NOT NULL,
  amount DECIMAL(10,2),
  PRIMARY KEY (id, sale_date)
) PARTITION BY RANGE (YEAR(sale_date)) (
  PARTITION p0 VALUES LESS THAN (2020),
  PARTITION p1 VALUES LESS THAN (2021),
  PARTITION p2 VALUES LESS THAN (2022),
  PARTITION p3 VALUES LESS THAN MAXVALUE
);
Slow query logEnable slow query logging to find problematic queries
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;  -- Log queries longer than 1 second
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Performance SchemaUse Performance Schema for monitoring
-- Find queries with full table scans
SELECT digest_text, count_star, sum_timer_wait
FROM performance_schema.events_statements_summary_by_digest
WHERE digest_text LIKE '%select%'
ORDER BY sum_timer_wait DESC LIMIT 10;
sys Schema (MySQL 5.7+)Use simplified views over Performance Schema
-- Show top 10 queries by average execution time
SELECT * FROM sys.statements_with_runtimes_in_95th_percentile LIMIT 10;

Error Handling

Command/ConceptDescriptionExample
SHOW WARNINGSDisplay warnings from the last statement
SHOW WARNINGS;
SHOW ERRORSDisplay errors from the last statement
SHOW ERRORS;
SHOW COUNT(*) WARNINGSDisplay the number of warnings
SHOW COUNT(*) WARNINGS;
SIGNALRaise error conditions from stored procedures
DELIMITER //
CREATE PROCEDURE check_negative_balance(IN account_id INT, IN amount DECIMAL(10,2))
BEGIN
  DECLARE current_balance DECIMAL(10,2);
  
  SELECT balance INTO current_balance FROM accounts WHERE id = account_id;
  
  IF current_balance - amount < 0 THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Insufficient funds', 
          MYSQL_ERRNO = 1001;
  END IF;
END //
DELIMITER ;
SQLSTATE valuesStandard error condition identifiers
'00000': Success
'01000': Warning
'23000': Integrity constraint violation
'42000': Syntax error or access rule violation
'45000': Custom user-defined error
DECLARE ... HANDLERHandle errors in stored procedures
DELIMITER //
CREATE PROCEDURE transfer_funds(
  IN from_account INT, 
  IN to_account INT, 
  IN amount DECIMAL(10,2)
)
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
    SELECT 'An error occurred. Transaction rolled back.' AS message;
  END;
  
  START TRANSACTION;
    UPDATE accounts SET balance = balance - amount WHERE id = from_account;
    UPDATE accounts SET balance = balance + amount WHERE id = to_account;
  COMMIT;
  
  SELECT 'Transfer completed successfully.' AS message;
END //
DELIMITER ;
Handler typesDifferent handler actions in stored procedures
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION -- Continue execution
DECLARE EXIT HANDLER FOR SQLEXCEPTION     -- Exit current block
DECLARE UNDO HANDLER FOR SQLEXCEPTION     -- Undo work (rarely used)
Handler condition typesDifferent ways to specify error conditions
-- By SQLSTATE
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' ...

-- By MySQL error code
DECLARE CONTINUE HANDLER FOR 1062 ...  -- Duplicate key

-- By named condition
DECLARE duplicate_key CONDITION FOR 1062;
DECLARE CONTINUE HANDLER FOR duplicate_key ...
GET DIAGNOSTICSGet detailed error information (MySQL 5.7+)
DELIMITER //
CREATE PROCEDURE p()
BEGIN
  DECLARE err_msg TEXT;
  DECLARE err_no INT;
  
  -- Execute a statement
  INSERT INTO table_with_unique_constraint VALUES(1, 'Duplicate');
  
  -- Get error info
  GET DIAGNOSTICS CONDITION 1
    err_no = MYSQL_ERRNO,
    err_msg = MESSAGE_TEXT;
    
  SELECT err_no, err_msg;
END //
DELIMITER ;
IGNORE keywordIgnore errors for a statement
-- Insert will continue even if some rows cause duplicate key errors
INSERT IGNORE INTO users (id, name) VALUES (1, 'John'), (2, 'Jane');
Error log locationFind MySQL error log location
SHOW VARIABLES LIKE 'log_error';
RESIGNALPass error along after handling it
DELIMITER //
CREATE PROCEDURE validate_and_transfer(from_acc INT, to_acc INT, amount DECIMAL(10,2))
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    -- Log the error
    INSERT INTO error_log (error_time, procedure_name) 
    VALUES (NOW(), 'validate_and_transfer');
    
    -- Re-raise the error
    RESIGNAL;
  END;
  
  -- Procedure body
  CALL transfer_funds(from_acc, to_acc, amount);
END //
DELIMITER ;

Working with Dates and Times

Function/CommandDescriptionExample
NOW()Current date and time
SELECT NOW(); -- 2023-07-19 15:30:45
CURDATE()Current date only
SELECT CURDATE(); -- 2023-07-19
CURTIME()Current time only
SELECT CURTIME(); -- 15:30:45
DATE_FORMAT()Format a date/time value
SELECT DATE_FORMAT(NOW(), '%W, %M %d, %Y'); -- Wednesday, July 19, 2023
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'); -- 2023-07-19 15:30:45
STR_TO_DATE()Convert string to date using format
SELECT STR_TO_DATE('July 19, 2023', '%M %d, %Y'); -- 2023-07-19
UNIX_TIMESTAMP()Convert to Unix timestamp (seconds since 1970-01-01)
SELECT UNIX_TIMESTAMP(NOW()); -- 1689778245
FROM_UNIXTIME()Convert Unix timestamp to datetime
SELECT FROM_UNIXTIME(1689778245); -- 2023-07-19 15:30:45
DATEDIFF()Difference between two dates in days
SELECT DATEDIFF('2023-07-30', '2023-07-19'); -- 11
TIMEDIFF()Difference between two times
SELECT TIMEDIFF('15:30:45', '10:15:30'); -- 05:15:15
DATE_ADD() / ADDDATE()Add time interval to a date
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY); -- 7 days from now
SELECT DATE_ADD('2023-07-19', INTERVAL 3 MONTH); -- 2023-10-19
DATE_SUB() / SUBDATE()Subtract time interval from a date
SELECT DATE_SUB(NOW(), INTERVAL 7 DAY); -- 7 days ago
SELECT DATE_SUB('2023-07-19', INTERVAL 3 MONTH); -- 2023-04-19
TIMESTAMPDIFF()Difference between dates in specified unit
SELECT TIMESTAMPDIFF(MONTH, '2022-01-01', '2023-07-19'); -- 18
SELECT TIMESTAMPDIFF(HOUR, '2023-07-19 10:00:00', '2023-07-19 15:30:45'); -- 5
DAYNAME()Get name of weekday
SELECT DAYNAME('2023-07-19'); -- Wednesday
MONTHNAME()Get name of month
SELECT MONTHNAME('2023-07-19'); -- July
EXTRACT()Extract part from date
SELECT EXTRACT(YEAR FROM '2023-07-19'); -- 2023
SELECT EXTRACT(MONTH FROM '2023-07-19'); -- 7
SELECT EXTRACT(DAY FROM '2023-07-19'); -- 19
YEAR(), MONTH(), DAY()Extract year, month, day from date
SELECT YEAR('2023-07-19'); -- 2023
SELECT MONTH('2023-07-19'); -- 7
SELECT DAY('2023-07-19'); -- 19
HOUR(), MINUTE(), SECOND()Extract hour, minute, second from time
SELECT HOUR('15:30:45'); -- 15
SELECT MINUTE('15:30:45'); -- 30
SELECT SECOND('15:30:45'); -- 45
LAST_DAY()Last day of the month for a date
SELECT LAST_DAY('2023-07-19'); -- 2023-07-31
MAKEDATE()Create a date from year and day of year
SELECT MAKEDATE(2023, 200); -- 2023-07-19 (200th day of 2023)
DATE()Extract the date part from a datetime
SELECT DATE('2023-07-19 15:30:45'); -- 2023-07-19
TIME()Extract the time part from a datetime
SELECT TIME('2023-07-19 15:30:45'); -- 15:30:45
Common date format specifiersFormat patterns for DATE_FORMAT() and STR_TO_DATE()
%Y - Year (4 digits)
%y - Year (2 digits)
%M - Month name (January..December)
%m - Month (01..12)
%d - Day of month (01..31)
%H - Hour (00..23)
%h - Hour (01..12)
%i - Minutes (00..59)
%s - Seconds (00..59)
%W - Weekday name (Sunday..Saturday)

String Functions

FunctionDescriptionExample
CONCAT()Concatenate strings
SELECT CONCAT('Hello', ' ', 'World'); -- 'Hello World'
CONCAT_WS()Concatenate with separator
SELECT CONCAT_WS('-', 'Hello', 'World', '2023'); -- 'Hello-World-2023'
LENGTH()String length in bytes
SELECT LENGTH('Hello'); -- 5
CHAR_LENGTH()String length in characters
SELECT CHAR_LENGTH('Hello😊'); -- 6 (handles multi-byte chars)
LEFT()Extract leftmost characters
SELECT LEFT('Hello World', 5); -- 'Hello'
RIGHT()Extract rightmost characters
SELECT RIGHT('Hello World', 5); -- 'World'
SUBSTRING() / SUBSTR()Extract a substring
SELECT SUBSTRING('Hello World', 7, 5); -- 'World'
SELECT SUBSTRING('Hello World', 7); -- 'World' (to end)
LOCATE() / POSITION()Find position of substring
SELECT LOCATE('World', 'Hello World'); -- 7
SELECT POSITION('World' IN 'Hello World'); -- 7
INSTR()Find position of substring
SELECT INSTR('Hello World', 'World'); -- 7
REPLACE()Replace all occurrences of a substring
SELECT REPLACE('Hello World', 'World', 'MySQL'); -- 'Hello MySQL'
TRIM()Remove leading and trailing spaces
SELECT TRIM('  Hello World  '); -- 'Hello World'
LTRIM(), RTRIM()Remove leading or trailing spaces
SELECT LTRIM('  Hello'); -- 'Hello'
SELECT RTRIM('Hello  '); -- 'Hello'
LOWER() / LCASE()Convert to lowercase
SELECT LOWER('Hello WORLD'); -- 'hello world'
UPPER() / UCASE()Convert to uppercase
SELECT UPPER('Hello world'); -- 'HELLO WORLD'
REPEAT()Repeat a string
SELECT REPEAT('MySQL ', 3); -- 'MySQL MySQL MySQL '
REVERSE()Reverse a string
SELECT REVERSE('Hello'); -- 'olleH'
INSERT()Insert substring at position
SELECT INSERT('Hello World', 7, 5, 'MySQL'); -- 'Hello MySQL'
LPAD()Left-pad a string to a length
SELECT LPAD('42', 5, '0'); -- '00042'
RPAD()Right-pad a string to a length
SELECT RPAD('Hello', 10, '.'); -- 'Hello.....'
SPACE()Return a string of spaces
SELECT CONCAT('Hello', SPACE(5), 'World'); -- 'Hello     World'
FORMAT()Format a number
SELECT FORMAT(12345.678, 2); -- '12,345.68' (locale-dependent)
FIELD()Return position of first match
SELECT FIELD('b', 'a', 'b', 'c'); -- 2
FIND_IN_SET()Find position in comma-separated list
SELECT FIND_IN_SET('b', 'a,b,c,d'); -- 2
SUBSTRING_INDEX()Return substring before n occurrences of delimiter
SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2); -- 'www.mysql'
SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2); -- 'mysql.com'
REGEXP / RLIKEPattern matching using regular expressions
SELECT 'MySQL' REGEXP '^My'; -- 1 (true)
SELECT * FROM users WHERE name REGEXP '^A[a-z]*$';
REGEXP_REPLACE() (MySQL 8.0+)Replace substrings using regex
SELECT REGEXP_REPLACE('Hello 123 World', '[0-9]+', 'number'); -- 'Hello number World'
REGEXP_LIKE() (MySQL 8.0+)Pattern matching with regex
SELECT REGEXP_LIKE('abc@example.com', '^[a-z]+@[a-z]+\.[a-z]+$'); -- 1

Numeric and Mathematical Functions

FunctionDescriptionExample
ABS()Absolute value
SELECT ABS(-15); -- 15
CEILING() / CEIL()Round up to nearest integer
SELECT CEILING(15.4); -- 16
FLOOR()Round down to nearest integer
SELECT FLOOR(15.7); -- 15
ROUND()Round to nearest integer or decimal places
SELECT ROUND(15.4); -- 15
SELECT ROUND(15.7); -- 16
SELECT ROUND(15.678, 2); -- 15.68
TRUNCATE()Truncate to specified number of decimal places
SELECT TRUNCATE(15.678, 2); -- 15.67
SELECT TRUNCATE(15.678, 0); -- 15
MOD() / %Modulo operation (remainder)
SELECT MOD(15, 4); -- 3
SELECT 15 % 4; -- 3
POW() / POWER()Raise to the power of
SELECT POW(2, 3); -- 8
SELECT POWER(2, 3); -- 8
SQRT()Square root
SELECT SQRT(16); -- 4
EXP()e raised to the power of
SELECT EXP(1); -- 2.718281828459045
LN()Natural logarithm
SELECT LN(2.718281828459045); -- 1
LOG()Natural logarithm or logarithm to base
SELECT LOG(2.718281828459045); -- 1
SELECT LOG(10, 100); -- 2 (log base 10 of 100)
LOG2()Log base 2
SELECT LOG2(8); -- 3
LOG10()Log base 10
SELECT LOG10(100); -- 2
PI()Value of π
SELECT PI(); -- 3.141593
SIN(), COS(), TAN()Trigonometric functions (radians)
SELECT SIN(PI()/2); -- 1
SELECT COS(PI()); -- -1
SELECT TAN(PI()/4); -- 1
ASIN(), ACOS(), ATAN()Inverse trigonometric functions
SELECT ASIN(1); -- 1.5707963267949 (π/2)
SELECT ACOS(-1); -- 3.141593 (π)
SELECT ATAN(1); -- 0.7853981633974483 (π/4)
DEGREES()Convert radians to degrees
SELECT DEGREES(PI()); -- 180
RADIANS()Convert degrees to radians
SELECT RADIANS(180); -- 3.141593
SIGN()Return sign of a number (-1, 0, 1)
SELECT SIGN(-15); -- -1
SELECT SIGN(0); -- 0
SELECT SIGN(15); -- 1
RAND()Random floating-point value (0 to 1)
SELECT RAND(); -- 0.123456789
SELECT RAND(42); -- Seeded random number
Random integer in rangeGenerate a random integer between min and max
SELECT FLOOR(RAND() * 10); -- 0 to 9
SELECT FLOOR(RAND() * 10) + 1; -- 1 to 10
SELECT FLOOR(RAND() * (max-min+1)) + min; -- min to max
DIVInteger division
SELECT 15 DIV 2; -- 7 (integer division)
/Floating-point division
SELECT 15 / 2; -- 7.5 (floating-point division)
CONV()Convert numbers between bases
SELECT CONV('A', 16, 10); -- 10 (hex to decimal)
SELECT CONV('1010', 2, 10); -- 10 (binary to decimal)
SELECT CONV('10', 10, 16); -- A (decimal to hex)
BIN()Convert to binary string
SELECT BIN(10); -- '1010'
OCT()Convert to octal string
SELECT OCT(10); -- '12'
HEX()Convert to hexadecimal string
SELECT HEX(255); -- 'FF'
FORMAT()Format number to specified decimal places
SELECT FORMAT(12345.678, 2); -- '12,345.68'

JSON Functions

FunctionDescriptionExample
JSON_ARRAY()Create a JSON array
SELECT JSON_ARRAY(1, 'abc', NULL, TRUE); -- [1, "abc", null, true]
JSON_OBJECT()Create a JSON object
SELECT JSON_OBJECT('id', 87, 'name', 'carrot'); -- {"id": 87, "name": "carrot"}
JSON_QUOTE()Quote a string as a JSON value
SELECT JSON_QUOTE('hello'); -- "hello"
JSON_CONTAINS()Check if JSON document contains specific value
SELECT JSON_CONTAINS('{"a": 1, "b": 2}', '1', '$.a'); -- 1 (true)
JSON_EXTRACT()Extract value from JSON document
SELECT JSON_EXTRACT('{"id": 14, "name": "Aztec"}', '$.name'); -- "Aztec"
-> operator (shorthand)Extract value from JSON document (MySQL 5.7.9+)
SELECT '{"id": 14, "name": "Aztec"}' -> '$.name'; -- "Aztec"
->> operator (unquoted)Extract value from JSON document without quotes (MySQL 5.7.13+)
SELECT '{"id": 14, "name": "Aztec"}' ->> '$.name'; -- Aztec
JSON_VALID()Check if value is valid JSON
SELECT JSON_VALID('{"a": 1}'); -- 1 (true)
SELECT JSON_VALID('{"a":'); -- 0 (false)

Administrative Commands

CommandDescriptionExample
SHOW DATABASESList all databases on the server
SHOW DATABASES;
SHOW TABLESList all tables in the current database
SHOW TABLES;
SHOW CREATE TABLEShow the CREATE statement for a table
SHOW CREATE TABLE users;
SHOW COLUMNSShow all columns in a table
SHOW COLUMNS FROM users;
DESCRIBE / DESCDisplay structure of a table (shorthand for SHOW COLUMNS)
DESCRIBE users;
DESC users;
SHOW INDEXShow all indexes in a table
SHOW INDEX FROM users;
SHOW PROCESSLISTShow active database connections and queries
SHOW PROCESSLIST;
SHOW STATUSShow server status variables
SHOW STATUS;
SHOW STATUS LIKE 'Threads%';
SHOW VARIABLESShow server configuration variables
SHOW VARIABLES;
SHOW VARIABLES LIKE 'max_connections';
SHOW ENGINESShow available storage engines
SHOW ENGINES;
SHOW ENGINE INNODB STATUSShow detailed InnoDB status
SHOW ENGINE INNODB STATUS;
SHOW GRANTSShow privileges for a user
SHOW GRANTS FOR 'user'@'localhost';
SHOW MASTER STATUSShow binary log status (for replication)
SHOW MASTER STATUS;
SHOW SLAVE STATUSShow replication slave status
SHOW SLAVE STATUS\G
SHOW WARNINGSShow warnings from the last statement
SHOW WARNINGS;
SHOW ERRORSShow errors from the last statement
SHOW ERRORS;
FLUSH PRIVILEGESReload grant tables (after user changes)
FLUSH PRIVILEGES;
FLUSH LOGSFlush all logs
FLUSH LOGS;
FLUSH TABLESClose all tables and flush caches
FLUSH TABLES;
OPTIMIZE TABLEDefragment and optimize a table
OPTIMIZE TABLE users;
ANALYZE TABLEAnalyze and store key distribution for a table
ANALYZE TABLE users;
CHECK TABLECheck table for errors
CHECK TABLE users;
REPAIR TABLERepair a possibly corrupted table
REPAIR TABLE users;
KILLTerminate a database thread
KILL 123;  -- Kill thread by ID
KILL QUERY 123;  -- Kill just a query

Replication Basics

Command/ConfigurationDescriptionExample
Master my.cnf settingsConfiguration for replication master server
# In /etc/my.cnf or my.ini (master server)
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW  # or MIXED, STATEMENT
binlog_do_db = db_to_replicate  # Optional: only replicate specific DB
binlog_ignore_db = db_to_ignore  # Optional: don't replicate specific DB
Slave my.cnf settingsConfiguration for replication slave server
# In /etc/my.cnf or my.ini (slave server)
[mysqld]
server-id = 2  # Must be unique
relay-log = relay-bin
read_only = 1  # Recommended for slave servers
replicate_do_db = db_to_replicate  # Optional
replicate_ignore_db = db_to_ignore  # Optional
Creating replication userCreate user with replication privileges on master
-- On master server
CREATE USER 'repl_user'@'slave_ip' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'slave_ip';
SHOW MASTER STATUSCheck binary log status on master
-- On master server
SHOW MASTER STATUS;

/* Output:
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 73       | test         |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
*/
Taking snapshot (simple method)Create a backup of data for initial slave setup
# On master server
mysqldump --all-databases --master-data=2 -u root -p > dump.sql

# Transfer dump.sql to slave server
scp dump.sql user@slave_ip:~/

# On slave server
mysql -u root -p < dump.sql
CHANGE MASTER TOConfigure slave to connect to master
-- On slave server
CHANGE MASTER TO
  MASTER_HOST='master_ip',
  MASTER_USER='repl_user',
  MASTER_PASSWORD='password',
  MASTER_LOG_FILE='mysql-bin.000003',  -- From SHOW MASTER STATUS
  MASTER_LOG_POS=73;                   -- From SHOW MASTER STATUS
START SLAVEStart replication on slave
-- On slave server
START SLAVE;
STOP SLAVEStop replication on slave
-- On slave server
STOP SLAVE;
SHOW SLAVE STATUSCheck replication status on slave
-- On slave server
SHOW SLAVE STATUS\G

/* Look for:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
*/
GTID Replication (MySQL 5.6+)Global Transaction Identifier based replication
# On both master and slave in my.cnf:
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON

# Then on slave:
CHANGE MASTER TO
  MASTER_HOST='master_ip',
  MASTER_USER='repl_user',
  MASTER_PASSWORD='password',
  MASTER_AUTO_POSITION=1;  -- Use GTID instead of binary log position
Skip a problematic transactionWhen a slave encounters an error
-- On slave server (MySQL 5.7+)
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;

-- For GTID replication (MySQL 5.7+)
STOP SLAVE;
SET @@GLOBAL.GTID_NEXT='specific_gtid_to_skip';
BEGIN; COMMIT;
SET @@GLOBAL.GTID_NEXT='AUTOMATIC';
START SLAVE;
Multi-source replication (MySQL 5.7+)Slave replicates from multiple masters
-- On slave server
CHANGE MASTER TO
  MASTER_HOST='master1_ip',
  MASTER_USER='repl_user1',
  MASTER_PASSWORD='password1',
  MASTER_LOG_FILE='mysql-bin.000003',
  MASTER_LOG_POS=73
  FOR CHANNEL 'master1';

CHANGE MASTER TO
  MASTER_HOST='master2_ip',
  MASTER_USER='repl_user2',
  MASTER_PASSWORD='password2',
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=120
  FOR CHANNEL 'master2';

START SLAVE FOR CHANNEL 'master1';
START SLAVE FOR CHANNEL 'master2';
Reset replicationReset slave or master state
-- On slave server
STOP SLAVE;
RESET SLAVE;  -- Or RESET SLAVE ALL to remove all connection info

-- On master server
RESET MASTER;  -- Deletes all binary logs

Security Best Practices

Practice/CommandDescriptionExample
Use strong passwordsCreate users with complex passwords
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'Str0ng_P@ssw0rd!';
Principle of least privilegeGrant only required permissions to users
-- Instead of:
GRANT ALL ON *.* TO 'user'@'localhost';

-- Better:
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'localhost';
GRANT SELECT ON app_db.sensitive_table TO 'reporting_user'@'localhost';
Use roles (MySQL 8.0+)Group privileges into roles for easier management
CREATE ROLE 'app_read', 'app_write';
GRANT SELECT ON app_db.* TO 'app_read';
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write';
GRANT 'app_read' TO 'reporting_user'@'localhost';
GRANT 'app_read', 'app_write' TO 'admin_user'@'localhost';
Remove anonymous usersDelete anonymous user accounts
-- Check for anonymous users
SELECT user, host FROM mysql.user WHERE user = '';

-- Remove anonymous users
DELETE FROM mysql.user WHERE user = '';
FLUSH PRIVILEGES;
Remove test databaseDrop the default test database
DROP DATABASE test;
DELETE FROM mysql.db WHERE db = 'test' OR db LIKE 'test\\_%';
FLUSH PRIVILEGES;
Restrict remote accessLimit access to specific hosts
-- Create users with specific host patterns
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'password';

-- Or secure the MySQL port in firewall
-- iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.0/24 -j ACCEPT
-- iptables -A INPUT -p tcp --dport 3306 -j DROP
Enable TLS/SSLEncrypt connections between clients and server
# In my.cnf
[mysqld]
ssl_ca=ca.pem
ssl_cert=server-cert.pem
ssl_key=server-key.pem

# Create user requiring SSL
CREATE USER 'secure_user'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
Use authentication pluginsBetter password security (MySQL 8.0+)
# MySQL 8.0+ uses caching_sha2_password by default
# For clients that don't support it:
CREATE USER 'app_user'@'localhost' 
IDENTIFIED WITH mysql_native_password BY 'password';
Password validationEnable password policy plugin
# In my.cnf
[mysqld]
plugin-load-add=validate_password.so
validate_password_policy=MEDIUM

# Check settings
SHOW VARIABLES LIKE 'validate_password%';
Audit user activityEnable audit log plugin (MySQL Enterprise)
# In my.cnf
[mysqld]
plugin-load-add=audit_log.so
audit_log_file=/var/log/mysql/audit.log
audit_log_policy=ALL
Lock user accountsTemporarily disable user access
-- MySQL 8.0+
ALTER USER 'app_user'@'localhost' ACCOUNT LOCK;

-- Re-enable later
ALTER USER 'app_user'@'localhost' ACCOUNT UNLOCK;
Password expirationForce regular password changes
-- Expire password after 90 days
ALTER USER 'app_user'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

-- Expire password now
ALTER USER 'app_user'@'localhost' PASSWORD EXPIRE;
Run with least privilegesRun MySQL server as unprivileged user
# Create mysql user if not exists
useradd -r -g mysql mysql

# Ensure MySQL data directory permissions
chown -R mysql:mysql /var/lib/mysql
Disable LOCAL INFILEPrevent loading data from client files
# In my.cnf
[mysqld]
local-infile=0

# Check setting
SHOW VARIABLES LIKE 'local_infile';
Prevent LOAD DATARestrict loading data from server files
# Limit secure_file_priv to a specific directory
# In my.cnf
[mysqld]
secure_file_priv=/var/mysql/secure_uploads

# Or disable completely
secure_file_priv=NULL

# Check setting
SHOW VARIABLES LIKE 'secure_file_priv';
Regular backupsEncrypt sensitive backup data
# Using encryption for backups
mysqldump --all-databases | openssl enc -aes-256-cbc -salt > backup.sql.enc

# Decrypt
openssl enc -d -aes-256-cbc -in backup.sql.enc > backup.sql
Skip networkingDisable network access for local-only instances
# In my.cnf
[mysqld]
skip-networking
socket=/var/run/mysqld/mysqld.sock
Monitor user accessRegularly review user accounts and privileges
-- List all users
SELECT user, host FROM mysql.user;

-- Review user privileges
SELECT * FROM mysql.user WHERE user = 'app_user';

Common Server Commands

CommandDescriptionExample
Start MySQL serverStart the MySQL service
# Linux (systemd)
sudo systemctl start mysql

# Linux (init.d)
sudo service mysql start

# Windows
net start mysql

# macOS
sudo launchctl load -F /Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist
Stop MySQL serverStop the MySQL service
# Linux (systemd)
sudo systemctl stop mysql

# Linux (init.d)
sudo service mysql stop

# Windows
net stop mysql

# macOS
sudo launchctl unload -F /Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist
Restart MySQL serverRestart the MySQL service
# Linux (systemd)
sudo systemctl restart mysql

# Linux (init.d)
sudo service mysql restart

# Windows
net stop mysql && net start mysql

# macOS
sudo launchctl unload -F /Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist
sudo launchctl load -F /Library/LaunchDaemons/com.oracle.oss.mysql.mysqld.plist
Check MySQL statusCheck if MySQL server is running
# Linux (systemd)
sudo systemctl status mysql

# Linux (init.d)
sudo service mysql status

# Windows
sc query mysql

# macOS
launchctl list | grep mysql
MySQL client loginConnect to the MySQL server
# Basic login
mysql -u root -p

# Specify host and port
mysql -h hostname -P 3306 -u username -p

# Specify database
mysql -u username -p database_name
MySQL client optionsUseful command line options
# Execute SQL from command line
mysql -u root -p -e "SELECT VERSION();"

# Vertical output format
mysql -u root -p -e "SELECT * FROM users LIMIT 2" --vertical

# Batch mode (tab-separated, non-interactive)
mysql -u root -p --batch -e "SELECT * FROM users LIMIT 2"

# XML output
mysql -u root -p -e "SELECT * FROM users LIMIT 2" --xml
MySQL backupBackup databases using mysqldump
# Backup single database
mysqldump -u root -p database_name > backup.sql

# Backup multiple databases
mysqldump -u root -p --databases db1 db2 > backup.sql

# Backup all databases
mysqldump -u root -p --all-databases > full_backup.sql

# Backup structure only (no data)
mysqldump -u root -p --no-data database_name > schema.sql
MySQL restoreRestore from backup
# Restore a database
mysql -u root -p database_name < backup.sql

# Restore multiple databases
mysql -u root -p < backup.sql
MySQL config filesCommon configuration file locations
# Linux
/etc/my.cnf
/etc/mysql/my.cnf
/etc/mysql/mysql.conf.d/mysqld.cnf

# Windows
C:\ProgramData\MySQL\MySQL Server x.y\my.ini

# macOS
/usr/local/mysql/etc/my.cnf
/etc/my.cnf
MySQL logsCommon log file locations
# Find error log location
mysql -u root -p -e "SHOW VARIABLES LIKE 'log_error';"

# Common error log locations
# Linux
/var/log/mysql/error.log
# Windows
C:\ProgramData\MySQL\MySQL Server x.y\Data\hostname.err
Reset root passwordReset forgotten root password
# Stop MySQL server
sudo systemctl stop mysql

# Start in safe mode
sudo mysqld_safe --skip-grant-tables --skip-networking &

# Connect without password
mysql -u root

# Set new password
mysql> USE mysql;
mysql> UPDATE user SET authentication_string=PASSWORD('new_password') 
       WHERE User='root';
mysql> FLUSH PRIVILEGES;
mysql> exit;

# Restart server normally
sudo systemctl restart mysql
Import large filesEfficiently import large SQL files
# Using source command
mysql -u root -p
mysql> USE database_name;
mysql> source /path/to/large_file.sql;

# Using shell pipe
pv large_file.sql | mysql -u root -p database_name
MySQL secure installationSecure a new MySQL installation
sudo mysql_secure_installation
MySQL command historyView and manage MySQL client command history
# View history file
cat ~/.mysql_history

# Clear history
rm ~/.mysql_history
touch ~/.mysql_history
Get MySQL versionCheck MySQL server version
# From command line
mysql -V
mysqladmin -V

# From MySQL client
SELECT VERSION();

Version Differences

MySQL VersionMajor Features/ChangesNotes
MySQL 8.0
  • Roles for access control
  • Improved data dictionary
  • JSON enhancements
  • Window functions (OVER clause)
  • Common Table Expressions (WITH)
  • Invisible indexes
  • Descending indexes
  • Default to utf8mb4 character set
  • Resource groups
  • Default authentication: caching_sha2_password
-- JSON functions
SELECT JSON_TABLE(...);

-- Window functions
SELECT name, salary, 
  AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees;

-- Common Table Expressions (CTE)
WITH RECURSIVE cte AS (
  SELECT 1 AS n
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;
MySQL 5.7
  • JSON data type
  • Generated columns
  • InnoDB as default engine
  • GTID improvements
  • Native partitioning
  • Performance Schema improvements
  • sys schema added
  • Support for IPv6
  • Default authentication: mysql_native_password
-- JSON data type
CREATE TABLE users (
  id INT PRIMARY KEY,
  data JSON
);

-- Generated columns
CREATE TABLE circle (
  radius DOUBLE,
  area DOUBLE AS (PI() * radius * radius) STORED
);
MySQL 5.6
  • Global Transaction IDs (GTIDs)
  • Improved replication
  • Online DDL operations
  • EXPLAIN for non-SELECT statements
  • Transportable tablespaces
  • Improved optimizer
  • Improved Performance Schema
  • Full-text search for InnoDB
-- EXPLAIN for non-SELECT
EXPLAIN UPDATE users SET status = 'active' WHERE id = 123;

-- Online ALTER TABLE
ALTER TABLE users ADD INDEX idx_email (email), 
ALGORITHM=INPLACE, LOCK=NONE;
MySQL 5.5
  • InnoDB storage engine improvements
  • Semi-synchronous replication
  • Performance Schema
  • Improved UTF-8 support
  • Plugin authentication
  • Partitioning enhancements
  • SIGNAL and RESIGNAL support
-- SIGNAL error handling
CREATE PROCEDURE check_value(value INT)
BEGIN
  IF value < 0 THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Value cannot be negative';
  END IF;
END;
Migration compatibility issues
  • 5.7 to 8.0: Authentication plugin change
  • 5.7 to 8.0: Removal of obsolete features
  • 5.7 to 8.0: SQL mode changes
  • 5.7 to 8.0: Reserved keywords added
  • 5.7 to 8.0: Case sensitivity changes
# 5.7 to 8.0 authentication plugin compatibility
CREATE USER 'user'@'localhost' 
IDENTIFIED WITH mysql_native_password BY 'password';

# Check SQL mode
SELECT @@sql_mode;

# Check reserved keywords
SELECT 'group' FROM users;  -- Error in 8.0, must use backticks
SELECT `group` FROM users;  -- Correct in 8.0
Version-specific syntax
  • 8.0: CTE and window functions
  • 8.0: TABLE statement
  • 8.0: EXCEPT and INTERSECT operators
  • 8.0: GROUPING function
  • 5.7+: JSON functions
  • 5.7+: Generated columns
  • 5.6+: EXPLAIN FORMAT=JSON
-- MySQL 8.0 only
SELECT * FROM table1 
EXCEPT 
SELECT * FROM table2;

-- TABLE statement (8.0+)
TABLE users;  -- Shorthand for SELECT * FROM users

-- 5.7+ JSON functions
SELECT JSON_EXTRACT(data, '$.name') FROM users;

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart