SlideShare a Scribd company logo
1 of 98
Download to read offline
MySQL Cookbook
Recipes for Developers
Sveta Smirnova, Percona
Alkin Tezuysal, ChistaDATA
l
ā€¢ MySQL Support Engineer
ā€¢ Author
MySQL Troubleshooting
MySQL Cookbook, 4th Edition
ā€¢ JSON UDF functions
ā€¢ FILTER clause for MySQL
ā€¢ Speaker
ā€¢ Percona Live, OOW, Fosdem,
DevConf, HighLoad...
Sveta Smirnova
l
SvetaSmirnova
svetasmirnova
@svetsmirnova
svetsmirnova
Letā€™s Connect!
ā€¢ Audience: DBAs
ā€¢ They do not write queries
ā€¢ They tune
ā€¢ Server options
ā€¢ Indexes
ā€¢ Table structure
Sveta the Speaker
4 Ā©2022 | Percona
ā€¢ For developers
ā€¢ New topic for me ā†’ challenging
ā€¢ In past I worked as a developer
MySQL Cookbook by Oā€™Reilly
5 Ā©2022 | Percona
ā€¢ For developers
ā€¢ New topic for me ā†’ challenging
ā€¢ In past I worked as a developer
ā€¢ I accepted
MySQL Cookbook by Oā€™Reilly
6 Ā©2022 | Percona
ā€¢ Queries
sql = "SELECT name, lastname " +
"FROM my_table " +
"WHERE id = " + my_id
15 years ago
7 Ā©2022 | Percona
ā€¢ Placeholders
sql = "SELECT name, lastname " +
"FROM my_table " +
"WHERE id = ?"
15 years ago
8 Ā©2022 | Percona
ā€¢ ORM
Speaker(name="Sveta",
lastname="Smirnova").save()
15 years ago
9 Ā©2022 | Percona
ā€¢ Nothing
Was anything changed?
10 Ā©2022 | Percona
ā€¢ Nothing
ā€¢ New MySQL APIs
ā€¢ Document Store support in MySQL
ā€¢ Object-oriented query language in MySQL
X DevAPI
Was anything changed?
11 Ā©2022 | Percona
Our Topics Today
12 Ā©2022 | Percona
mysql > SELECT ā€™Hello, world!ā€™;
+---------------+
| Hello, world! |
+---------------+
| Hello, world! |
+---------------+
1 row in set (0,00 sec)
MySQL CLI
13 Ā©2022 | Percona
ā€¢ Your SQL code debugger
ā€¢ Tested by
ā€¢ Millions of users
ā€¢ MySQL developers
ā€¢ Hundreds of tests at every release
ā€¢ Model API for your query
MySQL CLI
14 Ā©2022 | Percona
MySQL JS > print("Hello, world!")
Hello, world!
MySQL JS > py
Switching to Python mode...
MySQL Py > print("Hello, world!")
Hello, world!
MySQL Py > sql
Switching to SQL mode... Commands end with ;
MySQL SQL > SELECT ā€™Hello, world!ā€™;
+---------------+
| Hello, world! |
+---------------+
| Hello, world! |
+---------------+
1 row in set (0.0003 sec)
MySQL Shell
15 Ā©2022 | Percona
ā€¢ New command-line client with X DevAPI
support
ā€¢ SQL and Object-Oriented queries
ā€¢ MySQL Server administration
ā€¢ Utilities
ā€¢ Replication
ā€¢ InnoDB Cluster
ā€¢ Your own applications
MySQL Shell
16 Ā©2022 | Percona
ā€¢ Asynchronous code execution
ā€¢ Works with MySQL
ā€¢ As usual: by executing SQL
ā€¢ Querying tables as documents
ā€¢ Collections and documents support
Data storage in JSON
NoSQL-syntax, similar to MongoDBā€™s
X DevAPI
17 Ā©2022 | Percona
Standard SQL
SQL > SELECT thing, SUM(legs+arms) AS limbs
-> FROM limbs GROUP BY thing
-> HAVING limbs > 5;
+-----------+-------+
| thing | limbs |
+-----------+-------+
| armchair | 6 |
| centipede | 99 |
| insect | 6 |
| squid | 10 |
+-----------+-------+
4 rows in set (0.0004 sec)
Reading
18 Ā©2022 | Percona
X DevAPI for tables
JS > session.getCurrentSchema().
-> getTable(ā€™limbsā€™).
-> select().groupBy(ā€™thingā€™).
-> having(ā€™SUM(legs + arms) > 5ā€™)
->
+-----------+------+------+
| thing | legs | arms |
+-----------+------+------+
| armchair | 4 | 2 |
| centipede | 99 | 0 |
| insect | 6 | 0 |
| squid | 0 | 10 |
+-----------+------+------+
4 rows in set (0.0005 sec)
Reading
19 Ā©2022 | Percona
Document Store
Py > session.get_current_schema().
get_collection(ā€™collectionLimbsā€™).
find(ā€™IFNULL(arms, 0) + IFNULL(legs, 0) > 5ā€™)
{"_id":"000061ed7c240000000000000002",
"arms":0,"legs":6,"thing":"insect"}
{"_id":"000061ed7c240000000000000003",
"arms":10,"legs":0,"thing":"squid"}
{"_id":"000061ed7c240000000000000005",
"arms":0,"legs":99,"thing":"centipede"}
{"_id":"000061ed7c240000000000000007",
"arms":2,"legs":4,"thing":"armchair"}
4 documents in set (0.0004 sec)
Reading
20 Ā©2022 | Percona
Tables and Document Store
JS > session.getCurrentSchema().
-> getCollectionAsTable(ā€™collectionLimbsā€™).
-> select(ā€™JSON_EXTRACT(doc, "$.thing") AS thingā€™,
-> ā€™SUM(IFNULL(JSON_EXTRACT(doc, "$.arms"), 0) +
-> IFNULL(JSON_EXTRACT(doc, "$.legs"), 0)) AS limbsā€™).
-> groupBy(ā€™thingā€™).having(ā€™limbs > 5ā€™)
->
+-------------+-------+
| thing | limbs |
+-------------+-------+
| "insect" | 6 |
| "squid" | 10 |
| "centipede" | 99 |
| "armchair" | 6 |
+-------------+-------+
4 rows in set (0.0006 sec)
Reading
21 Ā©2022 | Percona
SQL code in Python
cursor = conn.cursor()
cursor.execute("SELECT id, name, cats FROM profile")
while True:
row = cursor.fetchone()
if row is None:
break
print(f"id: row[0], name: row[1], cats: row[2]")
Working with Results
22 Ā©2022 | Percona
X DevAPI for tables
result = session.get_schema(ā€™cookbookā€™).
get_table(ā€™profileā€™).
select(ā€™idā€™, ā€™nameā€™, ā€™catsā€™).execute()
while True:
row = result.fetch_one()
if row is None:
break
print(f"id: row[0], name: row[1], cats: row[2]")
Working with Results
23 Ā©2022 | Percona
Document Store
result = session.get_schema(ā€™cookbookā€™).
get_collection(ā€™collectionProfileā€™).
find().execute()
while True:
doc = result.fetch_one()
if doc is None:
break
print(f"id: doc[ā€™idā€™], name: doc[ā€™nameā€™], cats: doc[ā€™catsā€™]")
Working with Results
24 Ā©2022 | Percona
Tables and Document Store
result = session.get_schema(ā€™cookbookā€™).
get_collection_as_table(ā€™collectionProfileā€™).
select(ā€™JSON_EXTRACT(doc, "$.id") AS idā€™).
select(ā€™JSON_EXTRACT(doc, "$.name") AS nameā€™).
select(ā€™JSON_EXTRACT(doc, "$.cats") AS catsā€™).execute()
while True:
row = result.fetch_one()
if row is None:
break
print(f"id: row[0], name: row[1], cats: row[2]")
Working with Results
25 Ā©2022 | Percona
Standard SQL
INSERT INTO limbs(thing, legs, arms)
VALUES(ā€™catā€™, 2, 2);
Changing Data
26 Ā©2022 | Percona
X DevAPI for tables
JS > session.getSchema(ā€™cookbookā€™).
-> getTable(ā€™limbsā€™).
-> update().
-> set(ā€™legsā€™, 4).
-> set(ā€™armsā€™, 0).
-> where(ā€™thing = "cat"ā€™)
->
Changing Data
27 Ā©2022 | Percona
Document Store
Py > session.get_schema(ā€™cookbookā€™).
get_collection(ā€™collectionLimbsā€™).
add_or_replace_one(ā€™00006002f065000000000000006bā€™,
{"thing": "cat", "legs": 4, "arms": 0})
Changing Data
28 Ā©2022 | Percona
Tables and Document Store
JS > session.getSchema(ā€™cookbookā€™).
-> getCollectionAsTable(ā€™collectionLimbsā€™).
-> delete().
-> where(ā€™JSON_EXTRACT(doc, "$.thing") = "cat"ā€™)
->
Changing Data
29 Ā©2022 | Percona
Standard API: establishing connection
conn_params = {
"database": "test",
"host": "localhost",
"user": "sveta",
"password": "",
"charset": "cp1251"
}
conn = mysql.connector.connect(**conn_params)
Character Encoding
30 Ā©2022 | Percona
Standard API: SET NAMES
cursor.execute("SET NAMES utf8mb4")
Character Encoding
31 Ā©2022 | Percona
ā€¢ X DevAPI
ā€¢ Only utf8mb4
May not work with your connector!
Character Encoding
32 Ā©2022 | Percona
ā€¢ When was the longest trip per driver?
+--------+-------+------------+-------+
| rec_id | name | trav_date | miles |
+--------+-------+------------+-------+
| 1 | Ben | 2014-07-30 | 152 |
| 2 | Suzi | 2014-07-29 | 391 |
| 3 | Henry | 2014-07-29 | 300 |
| 4 | Henry | 2014-07-27 | 96 |
| 5 | Ben | 2014-07-29 | 131 |
| 6 | Henry | 2014-07-26 | 115 |
| 7 | Suzi | 2014-08-02 | 502 |
| 8 | Henry | 2014-08-01 | 197 |
| 9 | Ben | 2014-08-02 | 79 |
| 10 | Henry | 2014-07-30 | 203 |
+--------+-------+------------+-------+
Generating Summaries
33 Ā©2022 | Percona
Naive solution
mysql> SELECT name, trav_date, MAX(miles) AS ā€™longest tripā€™
-> FROM driver_log GROUP BY name;
ERROR 1055 (42000): ā€™cookbook.driver_log.trav_dateā€™ isnā€™t in GROUP BY
mysql> SET sql_mode=ā€;
Query OK, 0 rows affected (0,00 sec)
mysq> SELECT name, trav_date, MAX(miles) AS ā€™longest tripā€™
-> FROM driver_log GROUP BY name;
+-------+------------+--------------+
| name | trav_date | longest trip |
+-------+------------+--------------+
| Ben | 2014-07-30 | 152 |
| Suzi | 2014-07-29 | 502 |
| Henry | 2014-07-29 | 300 |
+-------+------------+--------------+
3 rows in set (0,00 sec)
Generating Summaries
34 Ā©2022 | Percona
Legacy solution
mysql> CREATE TEMPORARY TABLE t
-> SELECT name, MAX(miles) AS miles
-> FROM driver_log GROUP BY name;
mysql> SELECT d.name, d.trav_date, d.miles AS ā€™longest tripā€™
-> FROM driver_log AS d INNER JOIN t USING (name, miles)
-> ORDER BY name;
+-------+------------+--------------+
| name | trav_date | longest trip |
+-------+------------+--------------+
| Ben | 2014-07-30 | 152 |
| Henry | 2014-07-29 | 300 |
| Suzi | 2014-08-02 | 502 |
+-------+------------+--------------+
mysql> DROP TABLE t;
Generating Summaries
35 Ā©2022 | Percona
Common Table Expression (CTE)
mysql> WITH t AS
-> (SELECT name, MAX(miles) AS miles
-> FROM driver_log GROUP BY name)
-> SELECT d.name, d.trav_date, d.miles AS ā€™longest tripā€™
-> FROM driver_log AS d INNER JOIN t USING (name, miles)
-> ORDER BY name;
+-------+------------+--------------+
| name | trav_date | longest trip |
+-------+------------+--------------+
| Ben | 2014-07-30 | 152 |
| Henry | 2014-07-29 | 300 |
| Suzi | 2014-08-02 | 502 |
+-------+------------+--------------+
3 rows in set (0.01 sec)
Generating Summaries
36 Ā©2022 | Percona
CHECK Constraints
mysql> ALTER TABLE patients ADD CONSTRAINT date_check
-> CHECK((date_departed IS NULL) OR
-> (date_departed >= date_arrived));
mysql> INSERT INTO patients (national_id, name, surname,
-> gender, age, diagnosis, date_arrived, date_departed)
-> VALUES(ā€™34GD429520ā€™, ā€™Johnā€™, ā€™Doeā€™, ā€™Mā€™, 45,
-> ā€™Data Phobiaā€™, ā€™2020-07-20ā€™, ā€™2020-05-31ā€™);
ERROR 3819 (HY000): Check constraint ā€™date_checkā€™ is violated.
Validation and Formatting
37 Ā©2022 | Percona
JSON Schema for collections
JS > schema={
-> "$schema": "http://json-schema.org/draft-07/schema",
-> "id": "http://example.com/cookbook.json",
-> "type": "object",
-> "description": "Table limbs as a collection",
-> "properties": {
-> "thing": {"type": "string"},
-> "legs": {
-> "anyOf": [{"type": "number"},{"type": "null"}],
-> "default": 0
-> },
-> "arms": {
-> "anyOf": [{"type": "number"},{"type": "null"}],
-> "default": 0
-> }},
-> "required": ["thing","legs","arms"] }
Validation and Formatting
38 Ā©2022 | Percona
JS > collectionLimbs=session.getCurrentSchema().
-> createCollection(ā€™collectionLimbsā€™,
-> {"validation": {"level": "strict", "schema": schema}})
->
Validation and Formatting
39 Ā©2022 | Percona
Enumerating result
mysql> SELECT
-> ROW_NUMBER() OVER win AS turn,
-> first_name, last_name FROM name
-> WINDOW win
-> AS (ORDER BY RAND());
+------+------------+-----------+
| turn | first_name | last_name |
+------+------------+-----------+
| 1 | Devon | White |
| 2 | Kevin | Brown |
| 3 | Rondell | White |
| 4 | Vida | Blue |
| 5 | Pete | Gray |
+------+------------+-----------+
5 rows in set (0.00 sec)
Sequences
40 Ā©2022 | Percona
Several sequences in one query
mysql> WITH RECURSIVE sequences(id, geo, random) AS
-> (SELECT 1, 3, FLOOR(1+RAND()*5)
-> UNION ALL
-> SELECT id + 1, geo * 4, FLOOR(1+RAND()*5) FROM sequences WHERE id < 5)
-> SELECT * FROM sequences;
+------+------+--------+
| id | geo | random |
+------+------+--------+
| 1 | 3 | 4 |
| 2 | 12 | 4 |
| 3 | 48 | 2 |
| 4 | 192 | 2 |
| 5 | 768 | 3 |
+------+------+--------+
5 rows in set (0.00 sec)
Sequences
41 Ā©2022 | Percona
How many drivers on the road?
mysql> SELECT trav_date, COUNT(trav_date) AS drivers
-> FROM driver_log GROUP BY trav_date ORDER BY trav_date;
+------------+---------+
| trav_date | drivers |
+------------+---------+
| 2014-07-26 | 1 |
| 2014-07-27 | 1 |
| 2014-07-29 | 3 |
| 2014-07-30 | 2 |
| 2014-08-01 | 1 |
| 2014-08-02 | 2 |
+------------+---------+
Joins and Subqueries
42 Ā©2022 | Percona
Missed dates
mysql> CREATE TABLE dates (d DATE);
-> INSERT INTO dates (d)
-> VALUES(ā€™2014-07-26ā€™),(ā€™2014-07-27ā€™),(ā€™2014-07-28ā€™),
-> (ā€™2014-07-29ā€™),(ā€™2014-07-30ā€™),(ā€™2014-07-31ā€™),
-> (ā€™2014-08-01ā€™),(ā€™2014-08-02ā€™);
Joins and Subqueries
43 Ā©2022 | Percona
When drivers have rest?
mysql> SELECT dates.d
-> FROM dates LEFT JOIN driver_log
-> ON dates.d = driver_log.trav_date
-> WHERE driver_log.trav_date IS NULL;
+------------+
| d |
+------------+
| 2014-07-28 |
| 2014-07-31 |
+------------+
Joins and Subqueries
44 Ā©2022 | Percona
CTE: in one query
WITH RECURSIVE dates (d) AS (
SELECT ā€™2014-07-26ā€™
UNION ALL
SELECT d + INTERVAL 1 day
FROM dates
WHERE d < ā€™2014-08-02ā€™)
SELECT dates.d, COUNT(driver_log.trav_date) AS drivers
FROM dates LEFT JOIN driver_log
ON dates.d = driver_log.trav_date
GROUP BY d ORDER BY d;
Joins and Subqueries
45 Ā©2022 | Percona
Ranking: legacy way
mysql> SET @rownum := 0;
Query OK, 0 rows affected (0,00 sec)
mysql> SELECT @rownum := @rownum + 1 AS ā€˜rankā€˜, score FROM ranks ORDER BY score DESC;
+------+-------+
| rank | score |
+------+-------+
| 1 | 5 |
| 2 | 4 |
| 3 | 4 |
| 4 | 3 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 1 |
+------+-------+
8 rows in set, 1 warning (0,00 sec)
Statistics
46 Ā©2022 | Percona
The issue!
mysql> SHOW WARNINGSG
*************************** 1. row ***************************
Level: Warning
Code: 1287
Message: Setting user variables within expressions is
deprecated and will be removed in a future release. Consider
alternatives: ā€™SET variable=expression, ...ā€™, or
ā€™SELECT expression(s) INTO variables(s)ā€™.
1 row in set (0,00 sec)
Statistics
47 Ā©2022 | Percona
Ranking: Window Functions
mysql> SELECT ROW_NUMBER() OVER win AS ā€™rankā€™, score
-> FROM ranks WINDOW win AS (ORDER BY score DESC);
+------+-------+
| rank | score |
+------+-------+
| 1 | 5 |
| 2 | 4 |
| 3 | 4 |
| 4 | 3 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 1 |
+------+-------+
8 rows in set (0,00 sec)
Statistics
48 Ā©2022 | Percona
Repeating results
mysql> SELECT ROW_NUMBER() OVER win AS ā€™rowā€™,
-> RANK() OVER win AS ā€™rankā€™,
-> score FROM ranks WINDOW win AS (ORDER BY score DESC);
+------+------+-------+
| row | rank | score |
+------+------+-------+
| 1 | 1 | 5 |
| 2 | 2 | 4 |
| 3 | 2 | 4 |
| 4 | 4 | 3 |
| 5 | 5 | 2 |
| 6 | 5 | 2 |
| 7 | 5 | 2 |
| 8 | 8 | 1 |
+------+------+-------+
Statistics
49 Ā©2022 | Percona
Duplicate users
mysql> WITH tmp AS (
-> SELECT COUNT(*) AS count, last_name, first_name
-> FROM catalog_list GROUP BY last_name, first_name HAVING count > 1)
-> SELECT catalog_list.*
-> FROM tmp INNER JOIN catalog_list USING (last_name, first_name)
-> ORDER BY last_name, first_name;
+-----------+------------+----------------------+
| last_name | first_name | street |
+-----------+------------+----------------------+
| Baxter | Wallace | 57 3rd Ave. |
| BAXTER | WALLACE | 57 3rd Ave. |
| Baxter | Wallace | 57 3rd Ave., Apt 102 |
| Pinter | Marlene | 9 Sunset Trail |
| Pinter | Marlene | 9 Sunset Trail |
+-----------+------------+----------------------+
5 rows in set (0,00 sec)
Duplicates
50 Ā©2022 | Percona
ā€¢ Data type JSON
ā€¢ Compact storage
ā€¢ In-place update
On the source and replica
binlog_row_value_options=PARTIAL_JSON
ā€¢ Operators -> and ->>
ā€¢ Functions
Search, pattern support
Update
Validation, including JSON schema
Conversion
Documents join
JSON
51 Ā©2022 | Percona
ā€¢ JSON Path for queries
Names of book authors
mysql> SELECT JSON_EXTRACT(author, ā€™$.nameā€™) AS author
-> FROM book_authors;
+---------+
| author |
+---------+
| "Paul" |
| "Alkin" |
| "Sveta" |
+---------+
3 rows in set (0,00 sec)
JSON
52 Ā©2022 | Percona
ā€¢ JSON Path for queries
Names of book authors
mysql> SELECT author->ā€™$.nameā€™ AS author
-> FROM book_authors;
+---------+
| author |
+---------+
| "Paul" |
| "Alkin" |
| "Sveta" |
+---------+
3 rows in set (0,00 sec)
JSON
53 Ā©2022 | Percona
ā€¢ JSON Path for queries
Removing quotes
mysql> SELECT JSON_UNQUOTE(
-> JSON_EXTRACT(author, ā€™$.nameā€™)
-> ) AS author FROM book_authors;
+--------+
| author |
+--------+
| Paul |
| Alkin |
| Sveta |
+--------+
3 rows in set (0,00 sec)
JSON
54 Ā©2022 | Percona
ā€¢ JSON Path for queries
Removing quotes
mysql> SELECT author-Ā»ā€™$.nameā€™ AS author
-> FROM book_authors;
+--------+
| author |
+--------+
| Paul |
| Alkin |
| Sveta |
+--------+
3 rows in set (0,00 sec)
JSON
55 Ā©2022 | Percona
ā€¢ JSON Path for queries
First and last books
mysql> SELECT CONCAT(author-Ā»ā€™$.nameā€™, ā€™ ā€™, author-Ā»ā€™$.lastnameā€™) AS author,
-> author-Ā»ā€™$.books[0]ā€™ AS ā€˜First Bookā€˜, author-Ā»ā€™$.books[last]ā€™ AS ā€˜Last Bookā€˜
-> FROM book_authorsG
************************ 1. row ************************
author: Paul DuBois
First Book: Software Portability with imake: ...
Last Book: MySQL (Developerā€™s Library)
************************ 2. row ************************
author: Alkin Tezuysal
First Book: MySQL Cookbook
Last Book: MySQL Cookbook
************************ 3. row ************************
author: Sveta Smirnova
First Book: MySQL Troubleshooting
Last Book: MySQL Cookbook
JSON
56 Ā©2022 | Percona
Indexes
mysql> ALTER TABLE book_authors
-> ADD COLUMN lastname VARCHAR(255)
-> GENERATED ALWAYS AS
-> (JSON_UNQUOTE(JSON_EXTRACT(author, ā€™$.lastnameā€™)));
mysql> ALTER TABLE book_authors
-> ADD COLUMN name VARCHAR(255)
-> GENERATED ALWAYS AS (author-Ā»ā€™$.nameā€™);
mysql> CREATE INDEX author_name
-> ON book_authors(lastname, name);
JSON
57 Ā©2022 | Percona
l
Alkin will continue
Thank you!
Ā© 2022 | Percona
Letā€™s get connected with Alkin first
Alkin Tezuysal - EVP - Global Services @chistadata
ā— Linkedin : https://www.linkedin.com/in/askdba/
ā— Twitter: https://twitter.com/ask_dba
Open Source Database Evangelist
ā— Previously PlanetScale, Percona and Pythian as Technical Manager, SRE, DBA
ā— Previously Enterprise DBA , Informix, Oracle, DB2 , SQL Server
Author, Speaker, Mentor, and Coach
@ChistaDATA Inc. 2022
@ask_dba
Ā© 2022 | Percona
Alsoā€¦ Born to Sail, Forced to Work
@ChistaDATA Inc. 2022
@ask_dba
Ā© 2022 | Percona
About ChistaDATA Inc.
Founded in 2021 by Shiv Iyer - CEO and Principal
Has received 3M USD seed investment ( 2021)
Focusing on ClickHouse infrastructure engineering and performance operations
Whatā€™s ClickHouse anyway?
Services and Products around dedicated Managed Services, Support and Consulting
Weā€™re hiring globally DBAs, SREs and DevOps Engineers
@ChistaDATA Inc. 2022
@ask_dba
Ā© 2022 | Percona
About ClickHouse
Columnar Storage
SQL Compatible
Open Source (Apache 2.0)
Shared Nothing Architecture
Parallel Execution
Rich in Aggregate Functions
Super fast for Analytics workload
@ChistaDATA Inc. 2022
@ask_dba
Ā© 2022 | Percona
Agenda
Query Performance and Indexes
ā— Indexing basics
ā— Using a Full-Text Search
ā— MySQL Spatial Indexes and Geographical Data
ā— Using Histograms
@ChistaDATA Inc. 2022
@ask_dba
Ā© 2022 | Percona
Indexes in MySQL
ā— Table Scan
ā— Tree Traversal
ā— Leaf Nodes
ā— B-tree Structure
ā— Hash Indexing
ā— Spatial
ā— Full-text
ā— Histograms
@ask_dba
@ask_dba
Ā© 2022 | Percona
B-tree - is a self-balancing tree data structure.
@ask_dba
Ā© 2022 | Percona
Creating a Surrogate Primary Key
Problem
A table without a primary key is not performant enough
Solution
Add a primary key to all InnoDB tables.
@ask_dba
Ā© 2022 | Percona
mysql> ALTER TABLE `top_names`
-> ADD COLUMN `names_id` int unsigned NOT NULL
-> AUTO_INCREMENT PRIMARY KEY FIRST;
Query OK, 0 rows affected (0.44 sec)
Records: 0 Duplicates: 0 Warnings: 0
Add Primary Key
@ask_dba
Ā© 2022 | Percona
Deciding When a Query Can Use an Index
Problem
Your table has an index, but queries are still slow.
Solution
Check the query plan using EXPLAIN to make sure the right index has been used.
@ask_dba
Ā© 2022 | Percona
Use of Explain
mysql> EXPLAIN SELECT name_rank,top_name,name_count FROM top_names
-> WHERE name_rank < 10 ORDER BY name_count G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: top_names
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 161604
filtered: 33.33
Extra: Using where; Using filesort
1 row in set, 1 warning (0.00 sec)
@ask_dba
Ā© 2022 | Percona
Deciding the Order for Multiple Column Indexes
Use covering index
mysql> SELECT name_rank,top_name,name_count FROM top_names
-> WHERE name_rank < 10 ORDER BY name_count;
mysql> CREATE INDEX idx_name_rank_count ON top_names(name_count,name_rank);
Query OK, 0 rows affected (0.18 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> EXPLAIN SELECT name_rank,top_name,name_count FROM top_names
-> WHERE name_rank < 10 ORDER BY name_count;
*************************** 1. row ***************************
@ask_dba
Ā© 2022 | Percona
Using Full Text Indexes
Problem
You want to take advantage of a keyword search, but queries on text fields are slow.
Solution
Use FULLTEXT indexes for full-text searches.
@ask_dba
Ā© 2022 | Percona
FULLTEXT in action
FULLTEXT indexes have two other conditions:
1. They can be used only for CHAR, VARCHAR, or TEXT columns.
2. They can be used only when there is a MATCH() or AGAINST()
clause in a SELECT
statement.
@ask_dba
Ā© 2022 | Percona
Fulltext Index Modes
ā€¢ Natural language mode (default) is the search mode for simple phrases.
SELECT top_name,name_rank FROM top_names WHERE MATCH(top_name)
AGAINST("ANDREW" IN NATURAL LANGUAGE MODE);
@ask_dba
Ā© 2022 | Percona
Fulltext Index Modes
ā€¢ Boolean mode is for using Boolean operators in search mode.
SELECT top_name,name_rank FROM top_names WHERE MATCH(top_name)
AGAINST("+ANDREW +ANDY -ANN" IN BOOLEAN MODE);
@ask_dba
Ā© 2022 | Percona
Fulltext Index Modes
ā€¢ Query expansion mode is the search mode for similar or related values in a
search expression. In short, this mode will return relevant matches against a
searched
Keyword:
SELECT top_name,name_rank FROM top_names WHERE MATCH(top_name)
AGAINST("ANDY" WITH QUERY EXPANSION);
@ask_dba
Ā© 2022 | Percona
The optimizer will choose the none FULLTEXT index
mysql> EXPLAIN SELECT top_name,name_rank FROM top_names
-> WHERE top_name="ANDREW" G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: top_names
partitions: NULL
type: ref
possible_keys: idx_top_name,idx_desc_01,idx_desc_02
key: idx_top_name
key_len: 103
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
@ask_dba
Ā© 2022 | Percona
Create the FULLTEXT index
mysql> CREATE FULLTEXT INDEX idx_fulltext ON top_names(top_name);
Query OK, 0 rows affected, 1 warning (1.94 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> EXPLAIN SELECT top_name,name_rank FROM top_names
-> WHERE top_name="ANDREW" ƄG
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: top_names
partitions: NULL
type: ref
possible_keys: idx_top_name,idx_desc_01,idx_desc_02,idx_fulltext
key: idx_top_name
key_len: 103
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
@ask_dba
Ā© 2022 | Percona
Utilizing Spatial Indexes and Geographical Data
Problem
You want to store and query geographic coordinates effectively.
Solution
Use MySQLā€™s improved Spatial Reference System.
@ask_dba
Ā© 2022 | Percona
MySQLā€™s improved Spatial Reference System
Creating geometries in various formats
Converting geometries between formats
Accessing qualitative and quantitative properties of geometry
Describing relations between two geometries
Creating new geometries from existing ones
@ask_dba
Ā© 2022 | Percona
Different variations of geographic data references
mysql> SELECT * FROM INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS
-> WHERE SRS_ID=4326 OR SRS_ID=3857 ORDER BY SRS_ID DESC G
*************************** 1. row ***************************
SRS_NAME: WGS 84
SRS_ID: 4326
ORGANIZATION: EPSG
ORGANIZATION_COORDSYS_ID: 4326
DEFINITION: GEOGCS["WGS 84",DATUM["World Geodetic System 1984",
SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],
AXIS["Lat",NORTH],AXIS["Lon",EAST],AUTHORITY["EPSG","4326"]]
DESCRIPTION: NULL
ā€¦
@ask_dba
Ā© 2022 | Percona
SRS_ID 4326 represents map projections used in Google
Maps
mysql> CREATE TABLE poi
-> ( poi_id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> position POINT NOT NULL SRID 4326, name VARCHAR(200));
Query OK, 0 rows affected (0.02 sec)
@ask_dba
Ā© 2022 | Percona
Insert GeoSpatial data with ST_GeomFromText()
mysql> INSERT INTO poi VALUES (1, ST_GeomFromText('POINT(41.0211 29.0041)', 4326),
-> 'Maiden's Tower');
Query OK, 1 row affected (0.00 sec)
msyql> INSERT INTO poi VALUES (2, ST_GeomFromText('POINT(41.0256 28.9742)', 4326),
-> 'Galata Tower');
Query OK, 1 row affected (0.00 sec)
@ask_dba
Ā© 2022 | Percona
Create SPATIAL index
mysql> CREATE SPATIAL INDEX position ON poi (position);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
@ask_dba
Ā© 2022 | Percona
Measure the distance between coordinates ST_Distance()
mysql> SELECT ST_AsText(position) FROM poi WHERE poi_id = 1 INTO @tower1;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT ST_AsText(position) FROM poi WHERE poi_id = 2 INTO @tower2;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT ST_Distance(ST_GeomFromText(@tower1, 4326),
-> ST_GeomFromText(@tower2, 4326)) AS distance;
+--------------------+
| distance |
+--------------------+
| 2563.9276036976544 |
+--------------------+
1 row in set (0.00 sec)
@ask_dba
Ā© 2022 | Percona
Improved Earthā€™s spherical shape with
ST_Distance_Sphere ()
mysql> SELECT ST_Distance_Sphere(ST_GeomFromText(@tower1, 4326),
-> ST_GeomFromText(@tower2, 4326)) AS dist;
+--------------------+
| dist |
+--------------------+
| 2557.7412439442496 |
+--------------------+
1 row in set (0.00 sec)
@ask_dba
Ā© 2022 | Percona
Set a polygon with coordinates
mysql> SET @poly := ST_GeomFromText ( 'POLYGON(( 41.104897239651905 28.876082545638166,
-> 41.05727989444261 29.183699733138166,
-> 40.90384226781947 29.137007838606916,
-> 40.94119778455447 28.865096217513166,
-> 41.104897239651905 28.876082545638166))', 4326);
@ask_dba
@ask_dba
Ā© 2022 | Percona
Find two towers from Istanbul using SPATIAL index
ST_Within()
mysql> SELECT poi_id, name, ST_AsText(`position`)
-> AS `towers` FROM poi WHERE ST_Within( `position`, @poly) ;
+--------+----------------+------------------------+
| poi_id | name | towers |
+--------+----------------+------------------------+
| 1 | Maiden's Tower | POINT(41.0211 29.0041) |
| 2 | Galata Tower | POINT(41.0256 28.9742) |
+--------+----------------+------------------------+
2 rows in set (0.00 sec)
@ask_dba
@ask_dba
Ā© 2022 | Percona
Creating and Using Histograms
Problem
You want to join two or more tables, but MySQLā€™s optimizer does not choose the
right
query plan.
Solution
Use optimizer histograms to aid decision making.
@ask_dba
@ask_dba
Ā© 2022 | Percona
MySQL Optimizer Histograms
Lightweight data structures that store information about how many unique values exist in
each data bucket.
mysql> ANALYZE TABLE histograms UPDATE HISTOGRAM ON f1 G
*************************** 1. row ***************************
Table: cookbook.histograms
Op: histogram
Msg_type: status
Msg_text: Histogram statistics created for column 'f1'.
1 row in set (0,01 sec)
@ask_dba
@ask_dba
Ā© 2022 | Percona
Found in Information Schema
mysql> SELECT * FROM information_schema.column_statistics
-> WHERE table_name='histograms'ƄG
*************************** 1. row ***************************
SCHEMA_NAME: cookbook
TABLE_NAME: histograms
COLUMN_NAME: f1
HISTOGRAM: {"buckets": [[1, 0.16666666666666666], [2, 0.5], [3, 1.0]],
"data-type": "int",
"null-values": 0.0,
"collation-id": 8,
"last-updated": "2021-05-23 17:29:46.595599",
"sampling-rate": 1.0,
"histogram-type": "singleton",
"number-of-buckets-specified": 100}
1 row in set (0,00 sec)
@ask_dba
Ā© 2022 | Percona
Query before Histogram
mysql> grep filtered
PAGER set to 'grep filtered'
mysql> EXPLAIN SELECT * FROM histograms WHERE f1=1 G
filtered: 16.67
1 row in set, 1 warning (0,00 sec)
mysql> EXPLAIN SELECT * FROM histograms WHERE f1=2 G
filtered: 16.67
1 row in set, 1 warning (0,00 sec)
mysql> EXPLAIN SELECT * FROM histograms WHERE f1=3 G
filtered: 16.67
1 row in set, 1 warning (0,00 sec)
@ask_dba
Ā© 2022 | Percona
Query after Histogram
mysql> grep filtered
PAGER set to 'grep filtered'
mysql> EXPLAIN SELECT * FROM histograms WHERE f1=1 G
filtered: 16.67
1 row in set, 1 warning (0,00 sec)
mysql> EXPLAIN SELECT * FROM histograms WHERE f1=2 G
filtered: 33.33
1 row in set, 1 warning (0,00 sec)
mysql> EXPLAIN SELECT * FROM histograms WHERE f1=3 G
filtered: 50.00
1 row in set, 1 warning (0,00 sec)
@ask_dba
Ā© 2022 | Percona
Writing Performant Queries
Problem
You want to write efficient queries.
Solution
Study how MySQL accesses data, and adjust your queries to help MySQL perform
its job faster.
@ask_dba
Ā© 2022 | Percona
MySQLā€™s cost-based optimizer
1. Find the optimal method.
2. Check if the access method is useful.
3. Estimate the cost of using the access method.
4. Select the lowest-cost access method possible.
@ask_dba
Ā© 2022 | Percona
Query execution that MySQL chooses
1. Table scan
2. Index scan
3. Index lookup
4. Range scan
5. Index merge
6. Loose index scan
@ask_dba
Ā© 2022 | Percona
Conclusion - Slow Queries
Low cardinality
Large datasets
Multiple index traversal
Nonleading column lookup
Data type mismatch
Character set collation mismatch
Suffix lookup
Index as argument
Stale statistics
MySQL bug
@ask_dba
Ā© 2022 | Percona @ChistaDATA Inc. 2022
@ask_dba
Thank you!

More Related Content

Similar to MySQL Cookbook: Recipes for Developers, Alkin Tezuysal and Sveta Smirnova - Percona University

Curso de MySQL 5.7
Curso de MySQL 5.7Curso de MySQL 5.7
Curso de MySQL 5.7Eduardo Legatti
Ā 
Streaming ETL - from RDBMS to Dashboard with KSQL
Streaming ETL - from RDBMS to Dashboard with KSQLStreaming ETL - from RDBMS to Dashboard with KSQL
Streaming ETL - from RDBMS to Dashboard with KSQLBjoern Rost
Ā 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
Ā 
Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...
Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...
Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...Puppet
Ā 
BigQuery implementation
BigQuery implementationBigQuery implementation
BigQuery implementationSimon Su
Ā 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
Ā 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
Ā 
ą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdf
ą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdfą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdf
ą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdfAnilManage
Ā 
How to build and run oci containers
How to build and run oci containersHow to build and run oci containers
How to build and run oci containersSpyros Trigazis
Ā 
Ten Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQLTen Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQLanandology
Ā 
Fluentd 20150918 no_demo_public
Fluentd 20150918 no_demo_publicFluentd 20150918 no_demo_public
Fluentd 20150918 no_demo_publicSaewoong Lee
Ā 
What is MariaDB Server 10.3?
What is MariaDB Server 10.3?What is MariaDB Server 10.3?
What is MariaDB Server 10.3?Colin Charles
Ā 
MySQL 5.7 innodb_enhance_partii_20160527
MySQL 5.7 innodb_enhance_partii_20160527MySQL 5.7 innodb_enhance_partii_20160527
MySQL 5.7 innodb_enhance_partii_20160527Saewoong Lee
Ā 
Observability of InfluxDB IOx: Tracing, Metrics and System Tables
Observability of InfluxDB IOx: Tracing, Metrics and System TablesObservability of InfluxDB IOx: Tracing, Metrics and System Tables
Observability of InfluxDB IOx: Tracing, Metrics and System TablesInfluxData
Ā 
[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ ė° źµ¬ģ¶• ė°©ė²•
[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ  ė° źµ¬ģ¶• ė°©ė²•[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ  ė° źµ¬ģ¶• ė°©ė²•
[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ ė° źµ¬ģ¶• ė°©ė²•Open Source Consulting
Ā 
Percona Live UK 2014 Part III
Percona Live UK 2014  Part IIIPercona Live UK 2014  Part III
Percona Live UK 2014 Part IIIAlkin Tezuysal
Ā 

Similar to MySQL Cookbook: Recipes for Developers, Alkin Tezuysal and Sveta Smirnova - Percona University (20)

Tugas praktikum smbd
Tugas praktikum smbdTugas praktikum smbd
Tugas praktikum smbd
Ā 
Curso de MySQL 5.7
Curso de MySQL 5.7Curso de MySQL 5.7
Curso de MySQL 5.7
Ā 
Streaming ETL - from RDBMS to Dashboard with KSQL
Streaming ETL - from RDBMS to Dashboard with KSQLStreaming ETL - from RDBMS to Dashboard with KSQL
Streaming ETL - from RDBMS to Dashboard with KSQL
Ā 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Ā 
Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...
Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...
Cloudy with a Chance of Fireballs: Provisioning and Certificate Management in...
Ā 
BigQuery implementation
BigQuery implementationBigQuery implementation
BigQuery implementation
Ā 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Ā 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Ā 
ą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdf
ą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdfą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdf
ą¶…ą¶»ą·”ą¶« ą·„ą·šą¶»ą¶­ą·Š_MYSQL ą·ƒą·’ą¶‚ą·„ą¶½_TL_I_033__techlogiclk.com.pdf
Ā 
How to build and run oci containers
How to build and run oci containersHow to build and run oci containers
How to build and run oci containers
Ā 
Instalar MySQL CentOS
Instalar MySQL CentOSInstalar MySQL CentOS
Instalar MySQL CentOS
Ā 
Ten Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQLTen Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQL
Ā 
Mysql basics1
Mysql basics1Mysql basics1
Mysql basics1
Ā 
Fluentd 20150918 no_demo_public
Fluentd 20150918 no_demo_publicFluentd 20150918 no_demo_public
Fluentd 20150918 no_demo_public
Ā 
MySQL SQL Tutorial
MySQL SQL TutorialMySQL SQL Tutorial
MySQL SQL Tutorial
Ā 
What is MariaDB Server 10.3?
What is MariaDB Server 10.3?What is MariaDB Server 10.3?
What is MariaDB Server 10.3?
Ā 
MySQL 5.7 innodb_enhance_partii_20160527
MySQL 5.7 innodb_enhance_partii_20160527MySQL 5.7 innodb_enhance_partii_20160527
MySQL 5.7 innodb_enhance_partii_20160527
Ā 
Observability of InfluxDB IOx: Tracing, Metrics and System Tables
Observability of InfluxDB IOx: Tracing, Metrics and System TablesObservability of InfluxDB IOx: Tracing, Metrics and System Tables
Observability of InfluxDB IOx: Tracing, Metrics and System Tables
Ā 
[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ ė° źµ¬ģ¶• ė°©ė²•
[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ  ė° źµ¬ģ¶• ė°©ė²•[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ  ė° źµ¬ģ¶• ė°©ė²•
[ģ˜¤ķ”ˆģ†ŒģŠ¤ģ»Øģ„¤ķŒ…] ģæ ė²„ė„¤ķ‹°ģŠ¤ģ™€ ģæ ė²„ė„¤ķ‹°ģŠ¤ on ģ˜¤ķ”ˆģŠ¤ķƒ ė¹„źµ ė° źµ¬ģ¶• ė°©ė²•
Ā 
Percona Live UK 2014 Part III
Percona Live UK 2014  Part IIIPercona Live UK 2014  Part III
Percona Live UK 2014 Part III
Ā 

More from Alkin Tezuysal

Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
Ā 
Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024
Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024
Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024Alkin Tezuysal
Ā 
FOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdf
FOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdfFOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdf
FOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdfAlkin Tezuysal
Ā 
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdfMySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdfAlkin Tezuysal
Ā 
How OLTP to OLAP Archival Demystified
How OLTP to OLAP Archival DemystifiedHow OLTP to OLAP Archival Demystified
How OLTP to OLAP Archival DemystifiedAlkin Tezuysal
Ā 
My first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdfMy first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdfAlkin Tezuysal
Ā 
Integrating best of breed open source tools to vitess orchestrator pleu21
Integrating best of breed open source tools to vitess  orchestrator   pleu21Integrating best of breed open source tools to vitess  orchestrator   pleu21
Integrating best of breed open source tools to vitess orchestrator pleu21Alkin Tezuysal
Ā 
Vitess: Scalable Database Architecture - Kubernetes Community Days Africa Ap...
Vitess: Scalable Database Architecture -  Kubernetes Community Days Africa Ap...Vitess: Scalable Database Architecture -  Kubernetes Community Days Africa Ap...
Vitess: Scalable Database Architecture - Kubernetes Community Days Africa Ap...Alkin Tezuysal
Ā 
How to shard MariaDB like a pro - FOSDEM 2021
How to shard MariaDB like a pro  - FOSDEM 2021How to shard MariaDB like a pro  - FOSDEM 2021
How to shard MariaDB like a pro - FOSDEM 2021Alkin Tezuysal
Ā 
Vitess - Data on Kubernetes
Vitess -  Data on Kubernetes  Vitess -  Data on Kubernetes
Vitess - Data on Kubernetes Alkin Tezuysal
Ā 
MySQL Ecosystem in 2020
MySQL Ecosystem in 2020MySQL Ecosystem in 2020
MySQL Ecosystem in 2020Alkin Tezuysal
Ā 
Introduction to Vitess on Kubernetes for MySQL - Webinar
Introduction to Vitess on Kubernetes for MySQL -  WebinarIntroduction to Vitess on Kubernetes for MySQL -  Webinar
Introduction to Vitess on Kubernetes for MySQL - WebinarAlkin Tezuysal
Ā 
When is Myrocks good? 2020 Webinar Series
When is Myrocks good? 2020 Webinar SeriesWhen is Myrocks good? 2020 Webinar Series
When is Myrocks good? 2020 Webinar SeriesAlkin Tezuysal
Ā 
Mysql 8 vs Mariadb 10.4 Webinar 2020 Feb
Mysql 8 vs Mariadb 10.4 Webinar 2020 FebMysql 8 vs Mariadb 10.4 Webinar 2020 Feb
Mysql 8 vs Mariadb 10.4 Webinar 2020 FebAlkin Tezuysal
Ā 
Myrocks in the wild wild west! FOSDEM 2020
Myrocks in the wild wild west! FOSDEM 2020Myrocks in the wild wild west! FOSDEM 2020
Myrocks in the wild wild west! FOSDEM 2020Alkin Tezuysal
Ā 
Mysql 8 vs Mariadb 10.4 Highload++ 2019
Mysql 8 vs Mariadb 10.4 Highload++ 2019Mysql 8 vs Mariadb 10.4 Highload++ 2019
Mysql 8 vs Mariadb 10.4 Highload++ 2019Alkin Tezuysal
Ā 
When is MyRocks good?
When is MyRocks good? When is MyRocks good?
When is MyRocks good? Alkin Tezuysal
Ā 
How to upgrade like a boss to MySQL 8.0 - PLE19
How to upgrade like a boss to MySQL 8.0 -  PLE19How to upgrade like a boss to MySQL 8.0 -  PLE19
How to upgrade like a boss to MySQL 8.0 - PLE19Alkin Tezuysal
Ā 
Mysql ecosystem in 2019
Mysql ecosystem in 2019Mysql ecosystem in 2019
Mysql ecosystem in 2019Alkin Tezuysal
Ā 

More from Alkin Tezuysal (20)

Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Ā 
Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024
Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024
Design and Modeling for MySQL SCALE 21X Pasadena, CA Mar 2024
Ā 
FOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdf
FOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdfFOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdf
FOSSASIA - MySQL Cookbook 4e Journey APR 2023.pdf
Ā 
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdfMySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
MySQL Ecosystem in 2023 - FOSSASIA'23 - Alkin.pptx.pdf
Ā 
How OLTP to OLAP Archival Demystified
How OLTP to OLAP Archival DemystifiedHow OLTP to OLAP Archival Demystified
How OLTP to OLAP Archival Demystified
Ā 
My first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdfMy first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdf
Ā 
KubeCon_NA_2021
KubeCon_NA_2021KubeCon_NA_2021
KubeCon_NA_2021
Ā 
Integrating best of breed open source tools to vitess orchestrator pleu21
Integrating best of breed open source tools to vitess  orchestrator   pleu21Integrating best of breed open source tools to vitess  orchestrator   pleu21
Integrating best of breed open source tools to vitess orchestrator pleu21
Ā 
Vitess: Scalable Database Architecture - Kubernetes Community Days Africa Ap...
Vitess: Scalable Database Architecture -  Kubernetes Community Days Africa Ap...Vitess: Scalable Database Architecture -  Kubernetes Community Days Africa Ap...
Vitess: Scalable Database Architecture - Kubernetes Community Days Africa Ap...
Ā 
How to shard MariaDB like a pro - FOSDEM 2021
How to shard MariaDB like a pro  - FOSDEM 2021How to shard MariaDB like a pro  - FOSDEM 2021
How to shard MariaDB like a pro - FOSDEM 2021
Ā 
Vitess - Data on Kubernetes
Vitess -  Data on Kubernetes  Vitess -  Data on Kubernetes
Vitess - Data on Kubernetes
Ā 
MySQL Ecosystem in 2020
MySQL Ecosystem in 2020MySQL Ecosystem in 2020
MySQL Ecosystem in 2020
Ā 
Introduction to Vitess on Kubernetes for MySQL - Webinar
Introduction to Vitess on Kubernetes for MySQL -  WebinarIntroduction to Vitess on Kubernetes for MySQL -  Webinar
Introduction to Vitess on Kubernetes for MySQL - Webinar
Ā 
When is Myrocks good? 2020 Webinar Series
When is Myrocks good? 2020 Webinar SeriesWhen is Myrocks good? 2020 Webinar Series
When is Myrocks good? 2020 Webinar Series
Ā 
Mysql 8 vs Mariadb 10.4 Webinar 2020 Feb
Mysql 8 vs Mariadb 10.4 Webinar 2020 FebMysql 8 vs Mariadb 10.4 Webinar 2020 Feb
Mysql 8 vs Mariadb 10.4 Webinar 2020 Feb
Ā 
Myrocks in the wild wild west! FOSDEM 2020
Myrocks in the wild wild west! FOSDEM 2020Myrocks in the wild wild west! FOSDEM 2020
Myrocks in the wild wild west! FOSDEM 2020
Ā 
Mysql 8 vs Mariadb 10.4 Highload++ 2019
Mysql 8 vs Mariadb 10.4 Highload++ 2019Mysql 8 vs Mariadb 10.4 Highload++ 2019
Mysql 8 vs Mariadb 10.4 Highload++ 2019
Ā 
When is MyRocks good?
When is MyRocks good? When is MyRocks good?
When is MyRocks good?
Ā 
How to upgrade like a boss to MySQL 8.0 - PLE19
How to upgrade like a boss to MySQL 8.0 -  PLE19How to upgrade like a boss to MySQL 8.0 -  PLE19
How to upgrade like a boss to MySQL 8.0 - PLE19
Ā 
Mysql ecosystem in 2019
Mysql ecosystem in 2019Mysql ecosystem in 2019
Mysql ecosystem in 2019
Ā 

Recently uploaded

Motivation and Theory Maslow and Murray pdf
Motivation and Theory Maslow and Murray pdfMotivation and Theory Maslow and Murray pdf
Motivation and Theory Maslow and Murray pdfakankshagupta7348026
Ā 
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...Pooja Nehwal
Ā 
Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...
Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...
Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...Kayode Fayemi
Ā 
ANCHORING SCRIPT FOR A CULTURAL EVENT.docx
ANCHORING SCRIPT FOR A CULTURAL EVENT.docxANCHORING SCRIPT FOR A CULTURAL EVENT.docx
ANCHORING SCRIPT FOR A CULTURAL EVENT.docxNikitaBankoti2
Ā 
WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )
WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )
WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )Pooja Nehwal
Ā 
SaaStr Workshop Wednesday w: Jason Lemkin, SaaStr
SaaStr Workshop Wednesday w: Jason Lemkin, SaaStrSaaStr Workshop Wednesday w: Jason Lemkin, SaaStr
SaaStr Workshop Wednesday w: Jason Lemkin, SaaStrsaastr
Ā 
Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”
Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”
Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”soniya singh
Ā 
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...NETWAYS
Ā 
VVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara Services
VVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara ServicesVVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara Services
VVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara ServicesPooja Nehwal
Ā 
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...Sheetaleventcompany
Ā 
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...Krijn Poppe
Ā 
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...NETWAYS
Ā 
Philippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.pptPhilippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.pptssuser319dad
Ā 
call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@vikas rana
Ā 
Night 7k Call Girls Noida Sector 128 Call Me: 8448380779
Night 7k Call Girls Noida Sector 128 Call Me: 8448380779Night 7k Call Girls Noida Sector 128 Call Me: 8448380779
Night 7k Call Girls Noida Sector 128 Call Me: 8448380779Delhi Call girls
Ā 
Call Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night Enjoy
Call Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night EnjoyCall Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night Enjoy
Call Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night EnjoyPooja Nehwal
Ā 
George Lever - eCommerce Day Chile 2024
George Lever -  eCommerce Day Chile 2024George Lever -  eCommerce Day Chile 2024
George Lever - eCommerce Day Chile 2024eCommerce Institute
Ā 
AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024
AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024
AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024eCommerce Institute
Ā 
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...NETWAYS
Ā 
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxGenesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxFamilyWorshipCenterD
Ā 

Recently uploaded (20)

Motivation and Theory Maslow and Murray pdf
Motivation and Theory Maslow and Murray pdfMotivation and Theory Maslow and Murray pdf
Motivation and Theory Maslow and Murray pdf
Ā 
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Ā 
Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...
Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...
Governance and Nation-Building in Nigeria: Some Reflections on Options for Po...
Ā 
ANCHORING SCRIPT FOR A CULTURAL EVENT.docx
ANCHORING SCRIPT FOR A CULTURAL EVENT.docxANCHORING SCRIPT FOR A CULTURAL EVENT.docx
ANCHORING SCRIPT FOR A CULTURAL EVENT.docx
Ā 
WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )
WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )
WhatsApp šŸ“ž 9892124323 āœ…Call Girls In Juhu ( Mumbai )
Ā 
SaaStr Workshop Wednesday w: Jason Lemkin, SaaStr
SaaStr Workshop Wednesday w: Jason Lemkin, SaaStrSaaStr Workshop Wednesday w: Jason Lemkin, SaaStr
SaaStr Workshop Wednesday w: Jason Lemkin, SaaStr
Ā 
Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”
Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”
Call Girls in Sarojini Nagar Market Delhi šŸ’Æ Call Us šŸ”8264348440šŸ”
Ā 
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
Ā 
VVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara Services
VVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara ServicesVVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara Services
VVIP Call Girls Nalasopara : 9892124323, Call Girls in Nalasopara Services
Ā 
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
No Advance 8868886958 Chandigarh Call Girls , Indian Call Girls For Full Nigh...
Ā 
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Ā 
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fĆ¼r Container und Kubern...
Ā 
Philippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.pptPhilippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.ppt
Ā 
call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@
Ā 
Night 7k Call Girls Noida Sector 128 Call Me: 8448380779
Night 7k Call Girls Noida Sector 128 Call Me: 8448380779Night 7k Call Girls Noida Sector 128 Call Me: 8448380779
Night 7k Call Girls Noida Sector 128 Call Me: 8448380779
Ā 
Call Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night Enjoy
Call Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night EnjoyCall Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night Enjoy
Call Girl Number in Khar MumbaišŸ“² 9892124323 šŸ’ž Full Night Enjoy
Ā 
George Lever - eCommerce Day Chile 2024
George Lever -  eCommerce Day Chile 2024George Lever -  eCommerce Day Chile 2024
George Lever - eCommerce Day Chile 2024
Ā 
AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024
AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024
AndrƩs Ramƭrez Gossler, Facundo Schinnea - eCommerce Day Chile 2024
Ā 
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Ā 
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxGenesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Ā 

MySQL Cookbook: Recipes for Developers, Alkin Tezuysal and Sveta Smirnova - Percona University

  • 1. MySQL Cookbook Recipes for Developers Sveta Smirnova, Percona Alkin Tezuysal, ChistaDATA
  • 2. l ā€¢ MySQL Support Engineer ā€¢ Author MySQL Troubleshooting MySQL Cookbook, 4th Edition ā€¢ JSON UDF functions ā€¢ FILTER clause for MySQL ā€¢ Speaker ā€¢ Percona Live, OOW, Fosdem, DevConf, HighLoad... Sveta Smirnova
  • 4. ā€¢ Audience: DBAs ā€¢ They do not write queries ā€¢ They tune ā€¢ Server options ā€¢ Indexes ā€¢ Table structure Sveta the Speaker 4 Ā©2022 | Percona
  • 5. ā€¢ For developers ā€¢ New topic for me ā†’ challenging ā€¢ In past I worked as a developer MySQL Cookbook by Oā€™Reilly 5 Ā©2022 | Percona
  • 6. ā€¢ For developers ā€¢ New topic for me ā†’ challenging ā€¢ In past I worked as a developer ā€¢ I accepted MySQL Cookbook by Oā€™Reilly 6 Ā©2022 | Percona
  • 7. ā€¢ Queries sql = "SELECT name, lastname " + "FROM my_table " + "WHERE id = " + my_id 15 years ago 7 Ā©2022 | Percona
  • 8. ā€¢ Placeholders sql = "SELECT name, lastname " + "FROM my_table " + "WHERE id = ?" 15 years ago 8 Ā©2022 | Percona
  • 10. ā€¢ Nothing Was anything changed? 10 Ā©2022 | Percona
  • 11. ā€¢ Nothing ā€¢ New MySQL APIs ā€¢ Document Store support in MySQL ā€¢ Object-oriented query language in MySQL X DevAPI Was anything changed? 11 Ā©2022 | Percona
  • 12. Our Topics Today 12 Ā©2022 | Percona
  • 13. mysql > SELECT ā€™Hello, world!ā€™; +---------------+ | Hello, world! | +---------------+ | Hello, world! | +---------------+ 1 row in set (0,00 sec) MySQL CLI 13 Ā©2022 | Percona
  • 14. ā€¢ Your SQL code debugger ā€¢ Tested by ā€¢ Millions of users ā€¢ MySQL developers ā€¢ Hundreds of tests at every release ā€¢ Model API for your query MySQL CLI 14 Ā©2022 | Percona
  • 15. MySQL JS > print("Hello, world!") Hello, world! MySQL JS > py Switching to Python mode... MySQL Py > print("Hello, world!") Hello, world! MySQL Py > sql Switching to SQL mode... Commands end with ; MySQL SQL > SELECT ā€™Hello, world!ā€™; +---------------+ | Hello, world! | +---------------+ | Hello, world! | +---------------+ 1 row in set (0.0003 sec) MySQL Shell 15 Ā©2022 | Percona
  • 16. ā€¢ New command-line client with X DevAPI support ā€¢ SQL and Object-Oriented queries ā€¢ MySQL Server administration ā€¢ Utilities ā€¢ Replication ā€¢ InnoDB Cluster ā€¢ Your own applications MySQL Shell 16 Ā©2022 | Percona
  • 17. ā€¢ Asynchronous code execution ā€¢ Works with MySQL ā€¢ As usual: by executing SQL ā€¢ Querying tables as documents ā€¢ Collections and documents support Data storage in JSON NoSQL-syntax, similar to MongoDBā€™s X DevAPI 17 Ā©2022 | Percona
  • 18. Standard SQL SQL > SELECT thing, SUM(legs+arms) AS limbs -> FROM limbs GROUP BY thing -> HAVING limbs > 5; +-----------+-------+ | thing | limbs | +-----------+-------+ | armchair | 6 | | centipede | 99 | | insect | 6 | | squid | 10 | +-----------+-------+ 4 rows in set (0.0004 sec) Reading 18 Ā©2022 | Percona
  • 19. X DevAPI for tables JS > session.getCurrentSchema(). -> getTable(ā€™limbsā€™). -> select().groupBy(ā€™thingā€™). -> having(ā€™SUM(legs + arms) > 5ā€™) -> +-----------+------+------+ | thing | legs | arms | +-----------+------+------+ | armchair | 4 | 2 | | centipede | 99 | 0 | | insect | 6 | 0 | | squid | 0 | 10 | +-----------+------+------+ 4 rows in set (0.0005 sec) Reading 19 Ā©2022 | Percona
  • 20. Document Store Py > session.get_current_schema(). get_collection(ā€™collectionLimbsā€™). find(ā€™IFNULL(arms, 0) + IFNULL(legs, 0) > 5ā€™) {"_id":"000061ed7c240000000000000002", "arms":0,"legs":6,"thing":"insect"} {"_id":"000061ed7c240000000000000003", "arms":10,"legs":0,"thing":"squid"} {"_id":"000061ed7c240000000000000005", "arms":0,"legs":99,"thing":"centipede"} {"_id":"000061ed7c240000000000000007", "arms":2,"legs":4,"thing":"armchair"} 4 documents in set (0.0004 sec) Reading 20 Ā©2022 | Percona
  • 21. Tables and Document Store JS > session.getCurrentSchema(). -> getCollectionAsTable(ā€™collectionLimbsā€™). -> select(ā€™JSON_EXTRACT(doc, "$.thing") AS thingā€™, -> ā€™SUM(IFNULL(JSON_EXTRACT(doc, "$.arms"), 0) + -> IFNULL(JSON_EXTRACT(doc, "$.legs"), 0)) AS limbsā€™). -> groupBy(ā€™thingā€™).having(ā€™limbs > 5ā€™) -> +-------------+-------+ | thing | limbs | +-------------+-------+ | "insect" | 6 | | "squid" | 10 | | "centipede" | 99 | | "armchair" | 6 | +-------------+-------+ 4 rows in set (0.0006 sec) Reading 21 Ā©2022 | Percona
  • 22. SQL code in Python cursor = conn.cursor() cursor.execute("SELECT id, name, cats FROM profile") while True: row = cursor.fetchone() if row is None: break print(f"id: row[0], name: row[1], cats: row[2]") Working with Results 22 Ā©2022 | Percona
  • 23. X DevAPI for tables result = session.get_schema(ā€™cookbookā€™). get_table(ā€™profileā€™). select(ā€™idā€™, ā€™nameā€™, ā€™catsā€™).execute() while True: row = result.fetch_one() if row is None: break print(f"id: row[0], name: row[1], cats: row[2]") Working with Results 23 Ā©2022 | Percona
  • 24. Document Store result = session.get_schema(ā€™cookbookā€™). get_collection(ā€™collectionProfileā€™). find().execute() while True: doc = result.fetch_one() if doc is None: break print(f"id: doc[ā€™idā€™], name: doc[ā€™nameā€™], cats: doc[ā€™catsā€™]") Working with Results 24 Ā©2022 | Percona
  • 25. Tables and Document Store result = session.get_schema(ā€™cookbookā€™). get_collection_as_table(ā€™collectionProfileā€™). select(ā€™JSON_EXTRACT(doc, "$.id") AS idā€™). select(ā€™JSON_EXTRACT(doc, "$.name") AS nameā€™). select(ā€™JSON_EXTRACT(doc, "$.cats") AS catsā€™).execute() while True: row = result.fetch_one() if row is None: break print(f"id: row[0], name: row[1], cats: row[2]") Working with Results 25 Ā©2022 | Percona
  • 26. Standard SQL INSERT INTO limbs(thing, legs, arms) VALUES(ā€™catā€™, 2, 2); Changing Data 26 Ā©2022 | Percona
  • 27. X DevAPI for tables JS > session.getSchema(ā€™cookbookā€™). -> getTable(ā€™limbsā€™). -> update(). -> set(ā€™legsā€™, 4). -> set(ā€™armsā€™, 0). -> where(ā€™thing = "cat"ā€™) -> Changing Data 27 Ā©2022 | Percona
  • 28. Document Store Py > session.get_schema(ā€™cookbookā€™). get_collection(ā€™collectionLimbsā€™). add_or_replace_one(ā€™00006002f065000000000000006bā€™, {"thing": "cat", "legs": 4, "arms": 0}) Changing Data 28 Ā©2022 | Percona
  • 29. Tables and Document Store JS > session.getSchema(ā€™cookbookā€™). -> getCollectionAsTable(ā€™collectionLimbsā€™). -> delete(). -> where(ā€™JSON_EXTRACT(doc, "$.thing") = "cat"ā€™) -> Changing Data 29 Ā©2022 | Percona
  • 30. Standard API: establishing connection conn_params = { "database": "test", "host": "localhost", "user": "sveta", "password": "", "charset": "cp1251" } conn = mysql.connector.connect(**conn_params) Character Encoding 30 Ā©2022 | Percona
  • 31. Standard API: SET NAMES cursor.execute("SET NAMES utf8mb4") Character Encoding 31 Ā©2022 | Percona
  • 32. ā€¢ X DevAPI ā€¢ Only utf8mb4 May not work with your connector! Character Encoding 32 Ā©2022 | Percona
  • 33. ā€¢ When was the longest trip per driver? +--------+-------+------------+-------+ | rec_id | name | trav_date | miles | +--------+-------+------------+-------+ | 1 | Ben | 2014-07-30 | 152 | | 2 | Suzi | 2014-07-29 | 391 | | 3 | Henry | 2014-07-29 | 300 | | 4 | Henry | 2014-07-27 | 96 | | 5 | Ben | 2014-07-29 | 131 | | 6 | Henry | 2014-07-26 | 115 | | 7 | Suzi | 2014-08-02 | 502 | | 8 | Henry | 2014-08-01 | 197 | | 9 | Ben | 2014-08-02 | 79 | | 10 | Henry | 2014-07-30 | 203 | +--------+-------+------------+-------+ Generating Summaries 33 Ā©2022 | Percona
  • 34. Naive solution mysql> SELECT name, trav_date, MAX(miles) AS ā€™longest tripā€™ -> FROM driver_log GROUP BY name; ERROR 1055 (42000): ā€™cookbook.driver_log.trav_dateā€™ isnā€™t in GROUP BY mysql> SET sql_mode=ā€; Query OK, 0 rows affected (0,00 sec) mysq> SELECT name, trav_date, MAX(miles) AS ā€™longest tripā€™ -> FROM driver_log GROUP BY name; +-------+------------+--------------+ | name | trav_date | longest trip | +-------+------------+--------------+ | Ben | 2014-07-30 | 152 | | Suzi | 2014-07-29 | 502 | | Henry | 2014-07-29 | 300 | +-------+------------+--------------+ 3 rows in set (0,00 sec) Generating Summaries 34 Ā©2022 | Percona
  • 35. Legacy solution mysql> CREATE TEMPORARY TABLE t -> SELECT name, MAX(miles) AS miles -> FROM driver_log GROUP BY name; mysql> SELECT d.name, d.trav_date, d.miles AS ā€™longest tripā€™ -> FROM driver_log AS d INNER JOIN t USING (name, miles) -> ORDER BY name; +-------+------------+--------------+ | name | trav_date | longest trip | +-------+------------+--------------+ | Ben | 2014-07-30 | 152 | | Henry | 2014-07-29 | 300 | | Suzi | 2014-08-02 | 502 | +-------+------------+--------------+ mysql> DROP TABLE t; Generating Summaries 35 Ā©2022 | Percona
  • 36. Common Table Expression (CTE) mysql> WITH t AS -> (SELECT name, MAX(miles) AS miles -> FROM driver_log GROUP BY name) -> SELECT d.name, d.trav_date, d.miles AS ā€™longest tripā€™ -> FROM driver_log AS d INNER JOIN t USING (name, miles) -> ORDER BY name; +-------+------------+--------------+ | name | trav_date | longest trip | +-------+------------+--------------+ | Ben | 2014-07-30 | 152 | | Henry | 2014-07-29 | 300 | | Suzi | 2014-08-02 | 502 | +-------+------------+--------------+ 3 rows in set (0.01 sec) Generating Summaries 36 Ā©2022 | Percona
  • 37. CHECK Constraints mysql> ALTER TABLE patients ADD CONSTRAINT date_check -> CHECK((date_departed IS NULL) OR -> (date_departed >= date_arrived)); mysql> INSERT INTO patients (national_id, name, surname, -> gender, age, diagnosis, date_arrived, date_departed) -> VALUES(ā€™34GD429520ā€™, ā€™Johnā€™, ā€™Doeā€™, ā€™Mā€™, 45, -> ā€™Data Phobiaā€™, ā€™2020-07-20ā€™, ā€™2020-05-31ā€™); ERROR 3819 (HY000): Check constraint ā€™date_checkā€™ is violated. Validation and Formatting 37 Ā©2022 | Percona
  • 38. JSON Schema for collections JS > schema={ -> "$schema": "http://json-schema.org/draft-07/schema", -> "id": "http://example.com/cookbook.json", -> "type": "object", -> "description": "Table limbs as a collection", -> "properties": { -> "thing": {"type": "string"}, -> "legs": { -> "anyOf": [{"type": "number"},{"type": "null"}], -> "default": 0 -> }, -> "arms": { -> "anyOf": [{"type": "number"},{"type": "null"}], -> "default": 0 -> }}, -> "required": ["thing","legs","arms"] } Validation and Formatting 38 Ā©2022 | Percona
  • 39. JS > collectionLimbs=session.getCurrentSchema(). -> createCollection(ā€™collectionLimbsā€™, -> {"validation": {"level": "strict", "schema": schema}}) -> Validation and Formatting 39 Ā©2022 | Percona
  • 40. Enumerating result mysql> SELECT -> ROW_NUMBER() OVER win AS turn, -> first_name, last_name FROM name -> WINDOW win -> AS (ORDER BY RAND()); +------+------------+-----------+ | turn | first_name | last_name | +------+------------+-----------+ | 1 | Devon | White | | 2 | Kevin | Brown | | 3 | Rondell | White | | 4 | Vida | Blue | | 5 | Pete | Gray | +------+------------+-----------+ 5 rows in set (0.00 sec) Sequences 40 Ā©2022 | Percona
  • 41. Several sequences in one query mysql> WITH RECURSIVE sequences(id, geo, random) AS -> (SELECT 1, 3, FLOOR(1+RAND()*5) -> UNION ALL -> SELECT id + 1, geo * 4, FLOOR(1+RAND()*5) FROM sequences WHERE id < 5) -> SELECT * FROM sequences; +------+------+--------+ | id | geo | random | +------+------+--------+ | 1 | 3 | 4 | | 2 | 12 | 4 | | 3 | 48 | 2 | | 4 | 192 | 2 | | 5 | 768 | 3 | +------+------+--------+ 5 rows in set (0.00 sec) Sequences 41 Ā©2022 | Percona
  • 42. How many drivers on the road? mysql> SELECT trav_date, COUNT(trav_date) AS drivers -> FROM driver_log GROUP BY trav_date ORDER BY trav_date; +------------+---------+ | trav_date | drivers | +------------+---------+ | 2014-07-26 | 1 | | 2014-07-27 | 1 | | 2014-07-29 | 3 | | 2014-07-30 | 2 | | 2014-08-01 | 1 | | 2014-08-02 | 2 | +------------+---------+ Joins and Subqueries 42 Ā©2022 | Percona
  • 43. Missed dates mysql> CREATE TABLE dates (d DATE); -> INSERT INTO dates (d) -> VALUES(ā€™2014-07-26ā€™),(ā€™2014-07-27ā€™),(ā€™2014-07-28ā€™), -> (ā€™2014-07-29ā€™),(ā€™2014-07-30ā€™),(ā€™2014-07-31ā€™), -> (ā€™2014-08-01ā€™),(ā€™2014-08-02ā€™); Joins and Subqueries 43 Ā©2022 | Percona
  • 44. When drivers have rest? mysql> SELECT dates.d -> FROM dates LEFT JOIN driver_log -> ON dates.d = driver_log.trav_date -> WHERE driver_log.trav_date IS NULL; +------------+ | d | +------------+ | 2014-07-28 | | 2014-07-31 | +------------+ Joins and Subqueries 44 Ā©2022 | Percona
  • 45. CTE: in one query WITH RECURSIVE dates (d) AS ( SELECT ā€™2014-07-26ā€™ UNION ALL SELECT d + INTERVAL 1 day FROM dates WHERE d < ā€™2014-08-02ā€™) SELECT dates.d, COUNT(driver_log.trav_date) AS drivers FROM dates LEFT JOIN driver_log ON dates.d = driver_log.trav_date GROUP BY d ORDER BY d; Joins and Subqueries 45 Ā©2022 | Percona
  • 46. Ranking: legacy way mysql> SET @rownum := 0; Query OK, 0 rows affected (0,00 sec) mysql> SELECT @rownum := @rownum + 1 AS ā€˜rankā€˜, score FROM ranks ORDER BY score DESC; +------+-------+ | rank | score | +------+-------+ | 1 | 5 | | 2 | 4 | | 3 | 4 | | 4 | 3 | | 5 | 2 | | 6 | 2 | | 7 | 2 | | 8 | 1 | +------+-------+ 8 rows in set, 1 warning (0,00 sec) Statistics 46 Ā©2022 | Percona
  • 47. The issue! mysql> SHOW WARNINGSG *************************** 1. row *************************** Level: Warning Code: 1287 Message: Setting user variables within expressions is deprecated and will be removed in a future release. Consider alternatives: ā€™SET variable=expression, ...ā€™, or ā€™SELECT expression(s) INTO variables(s)ā€™. 1 row in set (0,00 sec) Statistics 47 Ā©2022 | Percona
  • 48. Ranking: Window Functions mysql> SELECT ROW_NUMBER() OVER win AS ā€™rankā€™, score -> FROM ranks WINDOW win AS (ORDER BY score DESC); +------+-------+ | rank | score | +------+-------+ | 1 | 5 | | 2 | 4 | | 3 | 4 | | 4 | 3 | | 5 | 2 | | 6 | 2 | | 7 | 2 | | 8 | 1 | +------+-------+ 8 rows in set (0,00 sec) Statistics 48 Ā©2022 | Percona
  • 49. Repeating results mysql> SELECT ROW_NUMBER() OVER win AS ā€™rowā€™, -> RANK() OVER win AS ā€™rankā€™, -> score FROM ranks WINDOW win AS (ORDER BY score DESC); +------+------+-------+ | row | rank | score | +------+------+-------+ | 1 | 1 | 5 | | 2 | 2 | 4 | | 3 | 2 | 4 | | 4 | 4 | 3 | | 5 | 5 | 2 | | 6 | 5 | 2 | | 7 | 5 | 2 | | 8 | 8 | 1 | +------+------+-------+ Statistics 49 Ā©2022 | Percona
  • 50. Duplicate users mysql> WITH tmp AS ( -> SELECT COUNT(*) AS count, last_name, first_name -> FROM catalog_list GROUP BY last_name, first_name HAVING count > 1) -> SELECT catalog_list.* -> FROM tmp INNER JOIN catalog_list USING (last_name, first_name) -> ORDER BY last_name, first_name; +-----------+------------+----------------------+ | last_name | first_name | street | +-----------+------------+----------------------+ | Baxter | Wallace | 57 3rd Ave. | | BAXTER | WALLACE | 57 3rd Ave. | | Baxter | Wallace | 57 3rd Ave., Apt 102 | | Pinter | Marlene | 9 Sunset Trail | | Pinter | Marlene | 9 Sunset Trail | +-----------+------------+----------------------+ 5 rows in set (0,00 sec) Duplicates 50 Ā©2022 | Percona
  • 51. ā€¢ Data type JSON ā€¢ Compact storage ā€¢ In-place update On the source and replica binlog_row_value_options=PARTIAL_JSON ā€¢ Operators -> and ->> ā€¢ Functions Search, pattern support Update Validation, including JSON schema Conversion Documents join JSON 51 Ā©2022 | Percona
  • 52. ā€¢ JSON Path for queries Names of book authors mysql> SELECT JSON_EXTRACT(author, ā€™$.nameā€™) AS author -> FROM book_authors; +---------+ | author | +---------+ | "Paul" | | "Alkin" | | "Sveta" | +---------+ 3 rows in set (0,00 sec) JSON 52 Ā©2022 | Percona
  • 53. ā€¢ JSON Path for queries Names of book authors mysql> SELECT author->ā€™$.nameā€™ AS author -> FROM book_authors; +---------+ | author | +---------+ | "Paul" | | "Alkin" | | "Sveta" | +---------+ 3 rows in set (0,00 sec) JSON 53 Ā©2022 | Percona
  • 54. ā€¢ JSON Path for queries Removing quotes mysql> SELECT JSON_UNQUOTE( -> JSON_EXTRACT(author, ā€™$.nameā€™) -> ) AS author FROM book_authors; +--------+ | author | +--------+ | Paul | | Alkin | | Sveta | +--------+ 3 rows in set (0,00 sec) JSON 54 Ā©2022 | Percona
  • 55. ā€¢ JSON Path for queries Removing quotes mysql> SELECT author-Ā»ā€™$.nameā€™ AS author -> FROM book_authors; +--------+ | author | +--------+ | Paul | | Alkin | | Sveta | +--------+ 3 rows in set (0,00 sec) JSON 55 Ā©2022 | Percona
  • 56. ā€¢ JSON Path for queries First and last books mysql> SELECT CONCAT(author-Ā»ā€™$.nameā€™, ā€™ ā€™, author-Ā»ā€™$.lastnameā€™) AS author, -> author-Ā»ā€™$.books[0]ā€™ AS ā€˜First Bookā€˜, author-Ā»ā€™$.books[last]ā€™ AS ā€˜Last Bookā€˜ -> FROM book_authorsG ************************ 1. row ************************ author: Paul DuBois First Book: Software Portability with imake: ... Last Book: MySQL (Developerā€™s Library) ************************ 2. row ************************ author: Alkin Tezuysal First Book: MySQL Cookbook Last Book: MySQL Cookbook ************************ 3. row ************************ author: Sveta Smirnova First Book: MySQL Troubleshooting Last Book: MySQL Cookbook JSON 56 Ā©2022 | Percona
  • 57. Indexes mysql> ALTER TABLE book_authors -> ADD COLUMN lastname VARCHAR(255) -> GENERATED ALWAYS AS -> (JSON_UNQUOTE(JSON_EXTRACT(author, ā€™$.lastnameā€™))); mysql> ALTER TABLE book_authors -> ADD COLUMN name VARCHAR(255) -> GENERATED ALWAYS AS (author-Ā»ā€™$.nameā€™); mysql> CREATE INDEX author_name -> ON book_authors(lastname, name); JSON 57 Ā©2022 | Percona
  • 59. Ā© 2022 | Percona Letā€™s get connected with Alkin first Alkin Tezuysal - EVP - Global Services @chistadata ā— Linkedin : https://www.linkedin.com/in/askdba/ ā— Twitter: https://twitter.com/ask_dba Open Source Database Evangelist ā— Previously PlanetScale, Percona and Pythian as Technical Manager, SRE, DBA ā— Previously Enterprise DBA , Informix, Oracle, DB2 , SQL Server Author, Speaker, Mentor, and Coach @ChistaDATA Inc. 2022 @ask_dba
  • 60. Ā© 2022 | Percona Alsoā€¦ Born to Sail, Forced to Work @ChistaDATA Inc. 2022 @ask_dba
  • 61. Ā© 2022 | Percona About ChistaDATA Inc. Founded in 2021 by Shiv Iyer - CEO and Principal Has received 3M USD seed investment ( 2021) Focusing on ClickHouse infrastructure engineering and performance operations Whatā€™s ClickHouse anyway? Services and Products around dedicated Managed Services, Support and Consulting Weā€™re hiring globally DBAs, SREs and DevOps Engineers @ChistaDATA Inc. 2022 @ask_dba
  • 62. Ā© 2022 | Percona About ClickHouse Columnar Storage SQL Compatible Open Source (Apache 2.0) Shared Nothing Architecture Parallel Execution Rich in Aggregate Functions Super fast for Analytics workload @ChistaDATA Inc. 2022 @ask_dba
  • 63. Ā© 2022 | Percona Agenda Query Performance and Indexes ā— Indexing basics ā— Using a Full-Text Search ā— MySQL Spatial Indexes and Geographical Data ā— Using Histograms @ChistaDATA Inc. 2022 @ask_dba
  • 64. Ā© 2022 | Percona Indexes in MySQL ā— Table Scan ā— Tree Traversal ā— Leaf Nodes ā— B-tree Structure ā— Hash Indexing ā— Spatial ā— Full-text ā— Histograms @ask_dba @ask_dba
  • 65. Ā© 2022 | Percona B-tree - is a self-balancing tree data structure. @ask_dba
  • 66. Ā© 2022 | Percona Creating a Surrogate Primary Key Problem A table without a primary key is not performant enough Solution Add a primary key to all InnoDB tables. @ask_dba
  • 67. Ā© 2022 | Percona mysql> ALTER TABLE `top_names` -> ADD COLUMN `names_id` int unsigned NOT NULL -> AUTO_INCREMENT PRIMARY KEY FIRST; Query OK, 0 rows affected (0.44 sec) Records: 0 Duplicates: 0 Warnings: 0 Add Primary Key @ask_dba
  • 68. Ā© 2022 | Percona Deciding When a Query Can Use an Index Problem Your table has an index, but queries are still slow. Solution Check the query plan using EXPLAIN to make sure the right index has been used. @ask_dba
  • 69. Ā© 2022 | Percona Use of Explain mysql> EXPLAIN SELECT name_rank,top_name,name_count FROM top_names -> WHERE name_rank < 10 ORDER BY name_count G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: top_names partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 161604 filtered: 33.33 Extra: Using where; Using filesort 1 row in set, 1 warning (0.00 sec) @ask_dba
  • 70. Ā© 2022 | Percona Deciding the Order for Multiple Column Indexes Use covering index mysql> SELECT name_rank,top_name,name_count FROM top_names -> WHERE name_rank < 10 ORDER BY name_count; mysql> CREATE INDEX idx_name_rank_count ON top_names(name_count,name_rank); Query OK, 0 rows affected (0.18 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> EXPLAIN SELECT name_rank,top_name,name_count FROM top_names -> WHERE name_rank < 10 ORDER BY name_count; *************************** 1. row *************************** @ask_dba
  • 71. Ā© 2022 | Percona Using Full Text Indexes Problem You want to take advantage of a keyword search, but queries on text fields are slow. Solution Use FULLTEXT indexes for full-text searches. @ask_dba
  • 72. Ā© 2022 | Percona FULLTEXT in action FULLTEXT indexes have two other conditions: 1. They can be used only for CHAR, VARCHAR, or TEXT columns. 2. They can be used only when there is a MATCH() or AGAINST() clause in a SELECT statement. @ask_dba
  • 73. Ā© 2022 | Percona Fulltext Index Modes ā€¢ Natural language mode (default) is the search mode for simple phrases. SELECT top_name,name_rank FROM top_names WHERE MATCH(top_name) AGAINST("ANDREW" IN NATURAL LANGUAGE MODE); @ask_dba
  • 74. Ā© 2022 | Percona Fulltext Index Modes ā€¢ Boolean mode is for using Boolean operators in search mode. SELECT top_name,name_rank FROM top_names WHERE MATCH(top_name) AGAINST("+ANDREW +ANDY -ANN" IN BOOLEAN MODE); @ask_dba
  • 75. Ā© 2022 | Percona Fulltext Index Modes ā€¢ Query expansion mode is the search mode for similar or related values in a search expression. In short, this mode will return relevant matches against a searched Keyword: SELECT top_name,name_rank FROM top_names WHERE MATCH(top_name) AGAINST("ANDY" WITH QUERY EXPANSION); @ask_dba
  • 76. Ā© 2022 | Percona The optimizer will choose the none FULLTEXT index mysql> EXPLAIN SELECT top_name,name_rank FROM top_names -> WHERE top_name="ANDREW" G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: top_names partitions: NULL type: ref possible_keys: idx_top_name,idx_desc_01,idx_desc_02 key: idx_top_name key_len: 103 ref: const rows: 1 filtered: 100.00 Extra: NULL 1 row in set, 1 warning (0.00 sec) @ask_dba
  • 77. Ā© 2022 | Percona Create the FULLTEXT index mysql> CREATE FULLTEXT INDEX idx_fulltext ON top_names(top_name); Query OK, 0 rows affected, 1 warning (1.94 sec) Records: 0 Duplicates: 0 Warnings: 1 mysql> EXPLAIN SELECT top_name,name_rank FROM top_names -> WHERE top_name="ANDREW" ƄG *************************** 1. row *************************** id: 1 select_type: SIMPLE table: top_names partitions: NULL type: ref possible_keys: idx_top_name,idx_desc_01,idx_desc_02,idx_fulltext key: idx_top_name key_len: 103 ref: const rows: 1 filtered: 100.00 Extra: NULL 1 row in set, 1 warning (0.00 sec) @ask_dba
  • 78. Ā© 2022 | Percona Utilizing Spatial Indexes and Geographical Data Problem You want to store and query geographic coordinates effectively. Solution Use MySQLā€™s improved Spatial Reference System. @ask_dba
  • 79. Ā© 2022 | Percona MySQLā€™s improved Spatial Reference System Creating geometries in various formats Converting geometries between formats Accessing qualitative and quantitative properties of geometry Describing relations between two geometries Creating new geometries from existing ones @ask_dba
  • 80. Ā© 2022 | Percona Different variations of geographic data references mysql> SELECT * FROM INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS -> WHERE SRS_ID=4326 OR SRS_ID=3857 ORDER BY SRS_ID DESC G *************************** 1. row *************************** SRS_NAME: WGS 84 SRS_ID: 4326 ORGANIZATION: EPSG ORGANIZATION_COORDSYS_ID: 4326 DEFINITION: GEOGCS["WGS 84",DATUM["World Geodetic System 1984", SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]], UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]], AXIS["Lat",NORTH],AXIS["Lon",EAST],AUTHORITY["EPSG","4326"]] DESCRIPTION: NULL ā€¦ @ask_dba
  • 81. Ā© 2022 | Percona SRS_ID 4326 represents map projections used in Google Maps mysql> CREATE TABLE poi -> ( poi_id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -> position POINT NOT NULL SRID 4326, name VARCHAR(200)); Query OK, 0 rows affected (0.02 sec) @ask_dba
  • 82. Ā© 2022 | Percona Insert GeoSpatial data with ST_GeomFromText() mysql> INSERT INTO poi VALUES (1, ST_GeomFromText('POINT(41.0211 29.0041)', 4326), -> 'Maiden's Tower'); Query OK, 1 row affected (0.00 sec) msyql> INSERT INTO poi VALUES (2, ST_GeomFromText('POINT(41.0256 28.9742)', 4326), -> 'Galata Tower'); Query OK, 1 row affected (0.00 sec) @ask_dba
  • 83. Ā© 2022 | Percona Create SPATIAL index mysql> CREATE SPATIAL INDEX position ON poi (position); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 @ask_dba
  • 84. Ā© 2022 | Percona Measure the distance between coordinates ST_Distance() mysql> SELECT ST_AsText(position) FROM poi WHERE poi_id = 1 INTO @tower1; Query OK, 1 row affected (0.00 sec) mysql> SELECT ST_AsText(position) FROM poi WHERE poi_id = 2 INTO @tower2; Query OK, 1 row affected (0.00 sec) mysql> SELECT ST_Distance(ST_GeomFromText(@tower1, 4326), -> ST_GeomFromText(@tower2, 4326)) AS distance; +--------------------+ | distance | +--------------------+ | 2563.9276036976544 | +--------------------+ 1 row in set (0.00 sec) @ask_dba
  • 85. Ā© 2022 | Percona Improved Earthā€™s spherical shape with ST_Distance_Sphere () mysql> SELECT ST_Distance_Sphere(ST_GeomFromText(@tower1, 4326), -> ST_GeomFromText(@tower2, 4326)) AS dist; +--------------------+ | dist | +--------------------+ | 2557.7412439442496 | +--------------------+ 1 row in set (0.00 sec) @ask_dba
  • 86. Ā© 2022 | Percona Set a polygon with coordinates mysql> SET @poly := ST_GeomFromText ( 'POLYGON(( 41.104897239651905 28.876082545638166, -> 41.05727989444261 29.183699733138166, -> 40.90384226781947 29.137007838606916, -> 40.94119778455447 28.865096217513166, -> 41.104897239651905 28.876082545638166))', 4326); @ask_dba @ask_dba
  • 87. Ā© 2022 | Percona Find two towers from Istanbul using SPATIAL index ST_Within() mysql> SELECT poi_id, name, ST_AsText(`position`) -> AS `towers` FROM poi WHERE ST_Within( `position`, @poly) ; +--------+----------------+------------------------+ | poi_id | name | towers | +--------+----------------+------------------------+ | 1 | Maiden's Tower | POINT(41.0211 29.0041) | | 2 | Galata Tower | POINT(41.0256 28.9742) | +--------+----------------+------------------------+ 2 rows in set (0.00 sec) @ask_dba @ask_dba
  • 88. Ā© 2022 | Percona Creating and Using Histograms Problem You want to join two or more tables, but MySQLā€™s optimizer does not choose the right query plan. Solution Use optimizer histograms to aid decision making. @ask_dba @ask_dba
  • 89. Ā© 2022 | Percona MySQL Optimizer Histograms Lightweight data structures that store information about how many unique values exist in each data bucket. mysql> ANALYZE TABLE histograms UPDATE HISTOGRAM ON f1 G *************************** 1. row *************************** Table: cookbook.histograms Op: histogram Msg_type: status Msg_text: Histogram statistics created for column 'f1'. 1 row in set (0,01 sec) @ask_dba @ask_dba
  • 90. Ā© 2022 | Percona Found in Information Schema mysql> SELECT * FROM information_schema.column_statistics -> WHERE table_name='histograms'ƄG *************************** 1. row *************************** SCHEMA_NAME: cookbook TABLE_NAME: histograms COLUMN_NAME: f1 HISTOGRAM: {"buckets": [[1, 0.16666666666666666], [2, 0.5], [3, 1.0]], "data-type": "int", "null-values": 0.0, "collation-id": 8, "last-updated": "2021-05-23 17:29:46.595599", "sampling-rate": 1.0, "histogram-type": "singleton", "number-of-buckets-specified": 100} 1 row in set (0,00 sec) @ask_dba
  • 91. Ā© 2022 | Percona Query before Histogram mysql> grep filtered PAGER set to 'grep filtered' mysql> EXPLAIN SELECT * FROM histograms WHERE f1=1 G filtered: 16.67 1 row in set, 1 warning (0,00 sec) mysql> EXPLAIN SELECT * FROM histograms WHERE f1=2 G filtered: 16.67 1 row in set, 1 warning (0,00 sec) mysql> EXPLAIN SELECT * FROM histograms WHERE f1=3 G filtered: 16.67 1 row in set, 1 warning (0,00 sec) @ask_dba
  • 92. Ā© 2022 | Percona Query after Histogram mysql> grep filtered PAGER set to 'grep filtered' mysql> EXPLAIN SELECT * FROM histograms WHERE f1=1 G filtered: 16.67 1 row in set, 1 warning (0,00 sec) mysql> EXPLAIN SELECT * FROM histograms WHERE f1=2 G filtered: 33.33 1 row in set, 1 warning (0,00 sec) mysql> EXPLAIN SELECT * FROM histograms WHERE f1=3 G filtered: 50.00 1 row in set, 1 warning (0,00 sec) @ask_dba
  • 93. Ā© 2022 | Percona Writing Performant Queries Problem You want to write efficient queries. Solution Study how MySQL accesses data, and adjust your queries to help MySQL perform its job faster. @ask_dba
  • 94. Ā© 2022 | Percona MySQLā€™s cost-based optimizer 1. Find the optimal method. 2. Check if the access method is useful. 3. Estimate the cost of using the access method. 4. Select the lowest-cost access method possible. @ask_dba
  • 95. Ā© 2022 | Percona Query execution that MySQL chooses 1. Table scan 2. Index scan 3. Index lookup 4. Range scan 5. Index merge 6. Loose index scan @ask_dba
  • 96. Ā© 2022 | Percona Conclusion - Slow Queries Low cardinality Large datasets Multiple index traversal Nonleading column lookup Data type mismatch Character set collation mismatch Suffix lookup Index as argument Stale statistics MySQL bug @ask_dba
  • 97. Ā© 2022 | Percona @ChistaDATA Inc. 2022 @ask_dba