Diving into MySQL 5.7
Advanced features
Gabriela Ferrara


@gabidavila
gabriela.io
@gabidavila
But first...
gabi
Developer Advocate @ Google
@gabidavila
MySQL 5.7 Adoption
@gabidavila
5.7
@gabidavila
What to expect?
● Online DDL modes
● JSON Data type
● Generated Columns
● sql_mode
● `sys` schema
@gabidavila
Online DDL
changes
On InnoDB
● INPLACE
● COPY
@gabidavila
@gabidavila
New Online DDL Changes on 5.7 | InnoDB Only
In-place | ALGORITHM=INPLACE
● Rename Index
● Add a Virtual Column
● VARCHAR from 1 to 255
@gabidavila
More info 🔗
@gabidavila
New Online DDL Changes on 5.7 | InnoDB Only
Table-copy | ALGORITHM=COPY
● VARCHAR from 255 to 65535
● Drop Stored Column
@gabidavila
More info 🔗
JSON
@gabidavila
Table `laps`
Column Type
id INT(10)
athlete VARCHAR(255)
distance (m) INT(10)
time (s) INT(10)
summary JSON
@gabidavila
SELECT * FROM `laps` LIMIT 1;
************************** 1. row ***************************

id: 1

athlete: Martha

distance: 3200

time: 1800

summary: {"weight": 55, "nickname": "M", "professional": true}

1 row in set (0.04 sec)
@gabidavila
@gabidavila
Display athlete, nickname and professional status
@gabidavila
+---------+----------+--------------+
| athlete | nickname | professional |
+---------+----------+--------------+
| Martha | "M" | true |
| Marcus | "Flash" | false |
| Martha | "M" | true |
| James | NULL | NULL |
| Marcus | "Flash" | false |
+---------+----------+--------------+
5 rows in set (0.04 sec)
SELECT
athlete,
JSON_EXTRACT(summary, '$.nickname') AS nickname,
JSON_EXTRACT(summary, '$.professional') AS professional
FROM laps;
@gabidavila
JSON_EXTRACT shortcut
@gabidavila
SELECT
athlete,
summary->'$.nickname' AS nickname,
summary->'$.professional' AS professional
FROM laps;
+---------+----------+--------------+
| athlete | nickname | professional |
+---------+----------+--------------+
| Martha | "M" | true |
| Marcus | "Flash" | false |
| Martha | "M" | true |
| James | NULL | NULL |
| Marcus | "Flash" | false |
+---------+----------+--------------+
5 rows in set (0.04 sec)
@gabidavila
JSON_UNQUOTE + JSON_EXTRACT shortcut
@gabidavila
SELECT
athlete,
summary->>'$.nickname' AS nickname,
summary->>'$.professional' AS professional
FROM laps;
+---------+----------+--------------+

| athlete | nickname | professional |

+---------+----------+--------------+

| Martha | M | true |

| Marcus | Flash | false |

| Martha | M | true |

| James | NULL | NULL |

| Marcus | Flash | false |

+---------+----------+--------------+

5 rows in set (0.04 sec)
@gabidavila
JSON_UNQUOTE + JSON_EXTRACT vs. ->>
@gabidavila
SELECT
athlete,
summary->>'$.nickname' AS nickname,
summary->>'$.professional' AS professional
FROM laps;
😎
SELECT
athlete,
JSON_UNQUOTE(JSON_EXTRACT(summary, '$.nickname')) AS nickname,
JSON_UNQUOTE(JSON_EXTRACT(summary, '$.professional')) AS professional
FROM laps;
😕
@gabidavila
JSON Path
● Access key:
● `$` refers to the document itself
● Keys can contain spaces
● JSON_EXTRACT() and -> are the same
● JSON_UNQUOTE(JSON_EXTRACT()) and ->> are the same
Generated
Columns
@gabidavila
@gabidavila
Types
Virtual
● No disk space
● In-place change operation
● Value generated on demand and
on every BEFORE triggers
Stored
● Uses disk space
● Copy operation
● Updated on every INSERT and
UPDATE
@gabidavila
@gabidavila
Virtual & Stored similarities
● They only know the table domain
● They have a type
● Allows expressions to be used such as:
○ Operators (product * quantity)
○ Built-in functions (YEAR(dob))
○ Literals ("expression", 1)
● Can be indexed
@gabidavila
Virtual & Stored limitations
● Subqueries ARE NOT allowed
● Custom functions ARE NOT supported
● Column rename is not possible
● Non deterministic functions are not supported (i.e. NOW())
@gabidavila
Example
@gabidavila
Modified table `laps`
Column Type
id INT(10)
athlete VARCHAR(255)
distance (m) INT(10)
time (s) INT(10)
summary JSON
speed (m/s) DOUBLE
Should it be VIRTUAL or STORED?
@gabidavila
Virtual
Adding the `speed` field to the
`laps` table
Dropping the `speed` field to the
`laps` table
Gist 🔗
ALTER TABLE `laps`
ADD COLUMN speed DOUBLE
GENERATED ALWAYS
AS (`distance` / `time`);
ALTER TABLE `laps`
DROP COLUMN speed;
@gabidavila
Virtual
Adding the `speed` field to the
`laps` table
Dropping the `speed` field to the
`laps` table
Gist 🔗
ALTER TABLE `laps`
ADD COLUMN speed DOUBLE
GENERATED ALWAYS
AS (`distance` / `time`);
-- completed in 82ms
ALTER TABLE `laps`
DROP COLUMN speed;
-- completed in 103ms
@gabidavila
Stored
Adding the `speed` field to the
`laps` table
Dropping the `speed` field to the
`laps` table
Gist 🔗
ALTER TABLE `laps`
ADD COLUMN speed DOUBLE
GENERATED ALWAYS
AS (`distance` / `time`) STORED;
-- 548 rows affected in 778ms
ALTER TABLE `laps`
DROP COLUMN speed;
-- completed in 3s 142ms
Generated
Columns & JSON
Indexing
DEMO!
sql_mode
@gabidavila
@gabidavila
SQL Modes | SELECT @@GLOBAL.sql_mode; | MySQL 5.6
On MySQL 5.6:
+--------------------------------------------+
| @@GLOBAL.sql_mode |
+--------------------------------------------+
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec)
@gabidavila
@gabidavila
SQL Modes | SELECT @@GLOBAL.sql_mode; | MySQL 5.7
On MySQL 5.7:
+-----------------------------------------------------------------------+
| @@GLOBAL.sql_mode |
+-----------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE, |

| ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------+
1 row in set (0.00 sec)
@gabidavila
@gabidavila
SQL Modes | Comparison
On MySQL 5.6:
! STRICT_TRANS_TABLES
! NO_ENGINE_SUBSTITUTION
On MySQL 5.7:
! STRICT_TRANS_TABLES
! NO_ENGINE_SUBSTITUTION
! NO_ZERO_IN_DATE*
! NO_ZERO_DATE*
! ERROR_FOR_DIVISION_BY_ZERO*
! ONLY_FULL_GROUP_BY
@gabidavila
@gabidavila
Example
@gabidavila
@gabidavila
Table `laps`
Column Type
id INT(10)
athlete VARCHAR(255)
distance (m) INT(10)
time (s) INT(10)
summary JSON
speed (m/s) DOUBLE
Gist 🔗
@gabidavila
@gabidavila
SELECT * FROM `laps`;
+----+---------+----------+------+

| id | athlete | distance | time |

+----+---------+----------+------+

| 1 | Martha | 3200 | 1800 |

| 2 | Marcus | 10000 | 2100 |

| 3 | Martha | 200 | 50 |

| 4 | James | 1600 | 480 |

| 5 | Marcus | 1600 | 240 |

+----+---------+----------+------+

5 rows in set (0.04 sec)
@gabidavila
@gabidavila
mysql> SELECT * FROM `laps` GROUP BY athlete;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and
contains nonaggregated column 'olympics.laps.id' which is not functionally
dependent on columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by
SELECT * FROM `laps` GROUP BY athlete;
SELECT `id`, `athlete`, `distance`, `time`, `summary`
FROM `laps`
GROUP BY athlete;
@gabidavila
mysql> SELECT * FROM `laps` GROUP BY athlete;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and
contains nonaggregated column 'olympics.laps.id' which is not functionally
dependent on columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by
SELECT * FROM `laps` GROUP BY athlete;
SELECT `id`, `athlete`, `distance`, `time`, `summary`
FROM `laps`
GROUP BY athlete;
@gabidavila
Why?
"Reject queries for which the select list, HAVING condition, or ORDER BY list
refer to nonaggregated columns that are neither named in the GROUP BY
clause nor are functionally dependent on (uniquely determined by) GROUP BY
columns."
@gabidavila
@gabidavila
Translation
This happens because the query is grouping by athlete and MySQL is
magically trying to “discover” which field should it bring as a result to the other
columns since there are more than one possible value per row.


This mode is known as ONLY_FULL_GROUP_BY.
More info 🔗
@gabidavila
@gabidavila
@gabidavila
Group By
● Columns should either be on the GROUP BY clause OR be using an
aggregator on the SELECT clause.
● Aggregators:
● ANY_VALUE()
● MIN()
● MAX()
● SUM()
● COUNT()
@gabidavila@gabidavila
`sys` schema
@gabidavila
MySQL `sys` schema
● Needs to be installed on 5.6
● Installed by default on 5.7
● MySQL Workbench 6.3 ships with a client for it
● If enabled, in production should be used for critical analytical cases
@gabidavila
@gabidavila
What can I do with it?
*High Cost SQL statements select * from sys.`x$statement_analysis`
Top 5% slower queries
select * from
sys.`x$statements_with_runtimes_in_95th_percentile`
Use temporary tables select * from sys.`statements_with_temp_tables`
Unused Indexes select * from sys.`schema_unused_indexes`
Full table scans
select * from
sys.`schema_tables_with_full_table_scans`
*x$ is actually a view duplicated from a table with a more user friendly format
@gabidavila
Other Changes
@gabidavila
Changes on 5.7
● Passwords can now have expiration date
● NO_ZERO_DATE, NO_ZERO_IN_DATE, ERROR_FOR_DIVISION_BY_ZERO
are deprecated and being default in STRICT mode in future versions
● Triggers now supports more than one event per table
● YEAR(2) was deprecated on 5.6, removed on 5.7
@gabidavila
Thank you!
● Twitter: @gabidavila
● Blog: http://gabriela.io
● Freenode: gabidavila
● Feedback: https://joind.in/talk/18d42
● References: MySQL documentation

More Related Content

PDF
DPC18 - OMG MySQL 8.0 is out! are we there yet?
PDF
php[tek] - Making the most out of MySQL
PDF
DPC18 - Making the most out of MySQL
PDF
MySQL 8.0: not only good, it’s GREAT! - PHP UK 2019
PDF
Introduction into MySQL Query Tuning for Dev[Op]s
PDF
Using JSON with MariaDB and MySQL
PDF
0888 learning-mysql
PDF
SunshinePHP 2017 - Making the most out of MySQL
DPC18 - OMG MySQL 8.0 is out! are we there yet?
php[tek] - Making the most out of MySQL
DPC18 - Making the most out of MySQL
MySQL 8.0: not only good, it’s GREAT! - PHP UK 2019
Introduction into MySQL Query Tuning for Dev[Op]s
Using JSON with MariaDB and MySQL
0888 learning-mysql
SunshinePHP 2017 - Making the most out of MySQL

What's hot (20)

PPTX
BGOUG15: JSON support in MySQL 5.7
PDF
Modern solutions for modern database load: improvements in the latest MariaDB...
PPTX
Php forum2015 tomas_final
PDF
Data Love Conference - Window Functions for Database Analytics
PDF
PDF
Introduction to MySQL Query Tuning for Dev[Op]s
PDF
Optimizer Histograms: When they Help and When Do Not?
PDF
Mentor Your Indexes
PDF
Laracon EU 2018: OMG MySQL 8.0 is out! are we there yet?
PDF
Brief introduction of Slick
PDF
Common Table Expressions in MariaDB 10.2
PDF
Sql query patterns, optimized
PDF
Cassandra nice use cases and worst anti patterns no sql-matters barcelona
PDF
Cassandra 3 new features 2016
PDF
The world's next top data model
PDF
Billion Goods in Few Categories: how Histograms Save a Life?
PDF
Understanding Query Execution
PDF
Advanced MySQL Query Tuning
PDF
Cassandra Materialized Views
BGOUG15: JSON support in MySQL 5.7
Modern solutions for modern database load: improvements in the latest MariaDB...
Php forum2015 tomas_final
Data Love Conference - Window Functions for Database Analytics
Introduction to MySQL Query Tuning for Dev[Op]s
Optimizer Histograms: When they Help and When Do Not?
Mentor Your Indexes
Laracon EU 2018: OMG MySQL 8.0 is out! are we there yet?
Brief introduction of Slick
Common Table Expressions in MariaDB 10.2
Sql query patterns, optimized
Cassandra nice use cases and worst anti patterns no sql-matters barcelona
Cassandra 3 new features 2016
The world's next top data model
Billion Goods in Few Categories: how Histograms Save a Life?
Understanding Query Execution
Advanced MySQL Query Tuning
Cassandra Materialized Views
Ad

Similar to Diving into MySQL 5.7: advanced features (20)

PDF
Developers' mDay 2017. - Bogdan Kecman Oracle
PDF
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
PDF
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
PDF
MySQL 5.7 Tutorial Dutch PHP Conference 2015
PDF
What's New MySQL 8.0?
PDF
Efficient MySQL Indexing and what's new in MySQL Explain
PDF
Why Use EXPLAIN FORMAT=JSON?
PDF
Optimizer overviewoow2014
PDF
RivieraJUG - MySQL 8.0 - What's new for developers.pdf
PDF
Optimizer percona live_ams2015
PPTX
cPanel now supports MySQL 8.0 - My Top Seven Features
PPTX
MySQL 8.0 Featured for Developers
PDF
MySQL Goes to 8! FOSDEM 2020 Database Track, January 2nd, 2020
PDF
My sql 5.7-upcoming-changes-v2
PDF
MySQL 5.7 - What's new, How to upgrade and Document Store
PDF
Developers’ mDay 2019. - Bogdan Kecman, Oracle – MySQL 8.0 – why upgrade
PPTX
Guide To Mastering The MySQL Query Execution Plan
ODP
MySQL 5.7 - What's new and How to upgrade
PDF
MySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
PDF
MySQL 8 Server Optimization Swanseacon 2018
Developers' mDay 2017. - Bogdan Kecman Oracle
Developers’ mDay u Banjoj Luci - Bogdan Kecman, Oracle – MySQL Server 8.0
MySQL 5.7. Tutorial - Dutch PHP Conference 2015
MySQL 5.7 Tutorial Dutch PHP Conference 2015
What's New MySQL 8.0?
Efficient MySQL Indexing and what's new in MySQL Explain
Why Use EXPLAIN FORMAT=JSON?
Optimizer overviewoow2014
RivieraJUG - MySQL 8.0 - What's new for developers.pdf
Optimizer percona live_ams2015
cPanel now supports MySQL 8.0 - My Top Seven Features
MySQL 8.0 Featured for Developers
MySQL Goes to 8! FOSDEM 2020 Database Track, January 2nd, 2020
My sql 5.7-upcoming-changes-v2
MySQL 5.7 - What's new, How to upgrade and Document Store
Developers’ mDay 2019. - Bogdan Kecman, Oracle – MySQL 8.0 – why upgrade
Guide To Mastering The MySQL Query Execution Plan
MySQL 5.7 - What's new and How to upgrade
MySQL 8 Tips and Tricks from Symfony USA 2018, San Francisco
MySQL 8 Server Optimization Swanseacon 2018
Ad

More from Gabriela Ferrara (14)

PDF
Serverless and you @ Women Who Code London 2020
PDF
Serverless and you - where do i run my stateless code
PDF
PHPDay 2019 - MySQL 8, not only good, great!
PDF
PyTexas - Machine learning APIs by Example
PDF
MySQL 8.0 Preview: What Is Coming?
PDF
LaravelSP - MySQL 5.7: introdução ao JSON Data Type
PDF
MySQL 5.7 - 
Tirando o Máximo Proveito
PDF
Strip your TEXT fields - Exeter Web Feb/2016
PDF
Strip your TEXT fields
PDF
Coding like a girl - DjangoCon
PDF
LAMP: Desenvolvendo além do trivial
PDF
Database Wizardry for Legacy Applications
PDF
Coding like a girl - Youtube presentation
PDF
Coding like a Girl
Serverless and you @ Women Who Code London 2020
Serverless and you - where do i run my stateless code
PHPDay 2019 - MySQL 8, not only good, great!
PyTexas - Machine learning APIs by Example
MySQL 8.0 Preview: What Is Coming?
LaravelSP - MySQL 5.7: introdução ao JSON Data Type
MySQL 5.7 - 
Tirando o Máximo Proveito
Strip your TEXT fields - Exeter Web Feb/2016
Strip your TEXT fields
Coding like a girl - DjangoCon
LAMP: Desenvolvendo além do trivial
Database Wizardry for Legacy Applications
Coding like a girl - Youtube presentation
Coding like a Girl

Recently uploaded (20)

PDF
“Introduction to Designing with AI Agents,” a Presentation from Amazon Web Se...
PPTX
Report in SIP_Distance_Learning_Technology_Impact.pptx
PDF
The Basics of Artificial Intelligence - Understanding the Key Concepts and Te...
PPTX
From XAI to XEE through Influence and Provenance.Controlling model fairness o...
PDF
CCUS-as-the-Missing-Link-to-Net-Zero_AksCurious.pdf
PDF
Peak of Data & AI Encore: Scalable Design & Infrastructure
PDF
FASHION-DRIVEN TEXTILES AS A CRYSTAL OF A NEW STREAM FOR STAKEHOLDER CAPITALI...
PDF
Introduction to c language from lecture slides
PPTX
Presentation - Principles of Instructional Design.pptx
PPTX
From Curiosity to ROI — Cost-Benefit Analysis of Agentic Automation [3/6]
PDF
GDG Cloud Southlake #45: Patrick Debois: The Impact of GenAI on Development a...
PPTX
Rise of the Digital Control Grid Zeee Media and Hope and Tivon FTWProject.com
PPTX
Slides World Game (s) Great Redesign Eco Economic Epochs.pptx
PDF
Revolutionizing recommendations a survey: a comprehensive exploration of mode...
PPTX
AQUEEL MUSHTAQUE FAKIH COMPUTER CENTER .
PDF
Rooftops detection with YOLOv8 from aerial imagery and a brief review on roof...
PPTX
CRM(Customer Relationship Managmnet) Presentation
PPTX
maintenance powerrpoint for adaprive and preventive
PDF
Domain-specific knowledge and context in large language models: challenges, c...
PDF
EGCB_Solar_Project_Presentation_and Finalcial Analysis.pdf
“Introduction to Designing with AI Agents,” a Presentation from Amazon Web Se...
Report in SIP_Distance_Learning_Technology_Impact.pptx
The Basics of Artificial Intelligence - Understanding the Key Concepts and Te...
From XAI to XEE through Influence and Provenance.Controlling model fairness o...
CCUS-as-the-Missing-Link-to-Net-Zero_AksCurious.pdf
Peak of Data & AI Encore: Scalable Design & Infrastructure
FASHION-DRIVEN TEXTILES AS A CRYSTAL OF A NEW STREAM FOR STAKEHOLDER CAPITALI...
Introduction to c language from lecture slides
Presentation - Principles of Instructional Design.pptx
From Curiosity to ROI — Cost-Benefit Analysis of Agentic Automation [3/6]
GDG Cloud Southlake #45: Patrick Debois: The Impact of GenAI on Development a...
Rise of the Digital Control Grid Zeee Media and Hope and Tivon FTWProject.com
Slides World Game (s) Great Redesign Eco Economic Epochs.pptx
Revolutionizing recommendations a survey: a comprehensive exploration of mode...
AQUEEL MUSHTAQUE FAKIH COMPUTER CENTER .
Rooftops detection with YOLOv8 from aerial imagery and a brief review on roof...
CRM(Customer Relationship Managmnet) Presentation
maintenance powerrpoint for adaprive and preventive
Domain-specific knowledge and context in large language models: challenges, c...
EGCB_Solar_Project_Presentation_and Finalcial Analysis.pdf

Diving into MySQL 5.7: advanced features

  • 1. Diving into MySQL 5.7 Advanced features Gabriela Ferrara 
 @gabidavila gabriela.io
  • 5. @gabidavila What to expect? ● Online DDL modes ● JSON Data type ● Generated Columns ● sql_mode ● `sys` schema @gabidavila
  • 6. Online DDL changes On InnoDB ● INPLACE ● COPY @gabidavila
  • 7. @gabidavila New Online DDL Changes on 5.7 | InnoDB Only In-place | ALGORITHM=INPLACE ● Rename Index ● Add a Virtual Column ● VARCHAR from 1 to 255 @gabidavila More info 🔗
  • 8. @gabidavila New Online DDL Changes on 5.7 | InnoDB Only Table-copy | ALGORITHM=COPY ● VARCHAR from 255 to 65535 ● Drop Stored Column @gabidavila More info 🔗
  • 10. @gabidavila Table `laps` Column Type id INT(10) athlete VARCHAR(255) distance (m) INT(10) time (s) INT(10) summary JSON
  • 11. @gabidavila SELECT * FROM `laps` LIMIT 1; ************************** 1. row ***************************
 id: 1
 athlete: Martha
 distance: 3200
 time: 1800
 summary: {"weight": 55, "nickname": "M", "professional": true}
 1 row in set (0.04 sec) @gabidavila
  • 12. @gabidavila Display athlete, nickname and professional status @gabidavila +---------+----------+--------------+ | athlete | nickname | professional | +---------+----------+--------------+ | Martha | "M" | true | | Marcus | "Flash" | false | | Martha | "M" | true | | James | NULL | NULL | | Marcus | "Flash" | false | +---------+----------+--------------+ 5 rows in set (0.04 sec) SELECT athlete, JSON_EXTRACT(summary, '$.nickname') AS nickname, JSON_EXTRACT(summary, '$.professional') AS professional FROM laps;
  • 13. @gabidavila JSON_EXTRACT shortcut @gabidavila SELECT athlete, summary->'$.nickname' AS nickname, summary->'$.professional' AS professional FROM laps; +---------+----------+--------------+ | athlete | nickname | professional | +---------+----------+--------------+ | Martha | "M" | true | | Marcus | "Flash" | false | | Martha | "M" | true | | James | NULL | NULL | | Marcus | "Flash" | false | +---------+----------+--------------+ 5 rows in set (0.04 sec)
  • 14. @gabidavila JSON_UNQUOTE + JSON_EXTRACT shortcut @gabidavila SELECT athlete, summary->>'$.nickname' AS nickname, summary->>'$.professional' AS professional FROM laps; +---------+----------+--------------+
 | athlete | nickname | professional |
 +---------+----------+--------------+
 | Martha | M | true |
 | Marcus | Flash | false |
 | Martha | M | true |
 | James | NULL | NULL |
 | Marcus | Flash | false |
 +---------+----------+--------------+
 5 rows in set (0.04 sec)
  • 15. @gabidavila JSON_UNQUOTE + JSON_EXTRACT vs. ->> @gabidavila SELECT athlete, summary->>'$.nickname' AS nickname, summary->>'$.professional' AS professional FROM laps; 😎 SELECT athlete, JSON_UNQUOTE(JSON_EXTRACT(summary, '$.nickname')) AS nickname, JSON_UNQUOTE(JSON_EXTRACT(summary, '$.professional')) AS professional FROM laps; 😕
  • 16. @gabidavila JSON Path ● Access key: ● `$` refers to the document itself ● Keys can contain spaces ● JSON_EXTRACT() and -> are the same ● JSON_UNQUOTE(JSON_EXTRACT()) and ->> are the same
  • 18. @gabidavila Types Virtual ● No disk space ● In-place change operation ● Value generated on demand and on every BEFORE triggers Stored ● Uses disk space ● Copy operation ● Updated on every INSERT and UPDATE @gabidavila
  • 19. @gabidavila Virtual & Stored similarities ● They only know the table domain ● They have a type ● Allows expressions to be used such as: ○ Operators (product * quantity) ○ Built-in functions (YEAR(dob)) ○ Literals ("expression", 1) ● Can be indexed
  • 20. @gabidavila Virtual & Stored limitations ● Subqueries ARE NOT allowed ● Custom functions ARE NOT supported ● Column rename is not possible ● Non deterministic functions are not supported (i.e. NOW())
  • 22. @gabidavila Modified table `laps` Column Type id INT(10) athlete VARCHAR(255) distance (m) INT(10) time (s) INT(10) summary JSON speed (m/s) DOUBLE Should it be VIRTUAL or STORED?
  • 23. @gabidavila Virtual Adding the `speed` field to the `laps` table Dropping the `speed` field to the `laps` table Gist 🔗 ALTER TABLE `laps` ADD COLUMN speed DOUBLE GENERATED ALWAYS AS (`distance` / `time`); ALTER TABLE `laps` DROP COLUMN speed;
  • 24. @gabidavila Virtual Adding the `speed` field to the `laps` table Dropping the `speed` field to the `laps` table Gist 🔗 ALTER TABLE `laps` ADD COLUMN speed DOUBLE GENERATED ALWAYS AS (`distance` / `time`); -- completed in 82ms ALTER TABLE `laps` DROP COLUMN speed; -- completed in 103ms
  • 25. @gabidavila Stored Adding the `speed` field to the `laps` table Dropping the `speed` field to the `laps` table Gist 🔗 ALTER TABLE `laps` ADD COLUMN speed DOUBLE GENERATED ALWAYS AS (`distance` / `time`) STORED; -- 548 rows affected in 778ms ALTER TABLE `laps` DROP COLUMN speed; -- completed in 3s 142ms
  • 27. DEMO!
  • 29. @gabidavila SQL Modes | SELECT @@GLOBAL.sql_mode; | MySQL 5.6 On MySQL 5.6: +--------------------------------------------+ | @@GLOBAL.sql_mode | +--------------------------------------------+ | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | +--------------------------------------------+ 1 row in set (0.00 sec) @gabidavila
  • 30. @gabidavila SQL Modes | SELECT @@GLOBAL.sql_mode; | MySQL 5.7 On MySQL 5.7: +-----------------------------------------------------------------------+ | @@GLOBAL.sql_mode | +-----------------------------------------------------------------------+ | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE, |
 | ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | +-----------------------------------------------------------------------+ 1 row in set (0.00 sec) @gabidavila
  • 31. @gabidavila SQL Modes | Comparison On MySQL 5.6: ! STRICT_TRANS_TABLES ! NO_ENGINE_SUBSTITUTION On MySQL 5.7: ! STRICT_TRANS_TABLES ! NO_ENGINE_SUBSTITUTION ! NO_ZERO_IN_DATE* ! NO_ZERO_DATE* ! ERROR_FOR_DIVISION_BY_ZERO* ! ONLY_FULL_GROUP_BY @gabidavila
  • 33. @gabidavila Table `laps` Column Type id INT(10) athlete VARCHAR(255) distance (m) INT(10) time (s) INT(10) summary JSON speed (m/s) DOUBLE Gist 🔗 @gabidavila
  • 34. @gabidavila SELECT * FROM `laps`; +----+---------+----------+------+
 | id | athlete | distance | time |
 +----+---------+----------+------+
 | 1 | Martha | 3200 | 1800 |
 | 2 | Marcus | 10000 | 2100 |
 | 3 | Martha | 200 | 50 |
 | 4 | James | 1600 | 480 |
 | 5 | Marcus | 1600 | 240 |
 +----+---------+----------+------+
 5 rows in set (0.04 sec) @gabidavila
  • 35. @gabidavila mysql> SELECT * FROM `laps` GROUP BY athlete; ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'olympics.laps.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by SELECT * FROM `laps` GROUP BY athlete; SELECT `id`, `athlete`, `distance`, `time`, `summary` FROM `laps` GROUP BY athlete;
  • 36. @gabidavila mysql> SELECT * FROM `laps` GROUP BY athlete; ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'olympics.laps.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by SELECT * FROM `laps` GROUP BY athlete; SELECT `id`, `athlete`, `distance`, `time`, `summary` FROM `laps` GROUP BY athlete;
  • 37. @gabidavila Why? "Reject queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on (uniquely determined by) GROUP BY columns." @gabidavila
  • 38. @gabidavila Translation This happens because the query is grouping by athlete and MySQL is magically trying to “discover” which field should it bring as a result to the other columns since there are more than one possible value per row. 
 This mode is known as ONLY_FULL_GROUP_BY. More info 🔗 @gabidavila
  • 40. @gabidavila Group By ● Columns should either be on the GROUP BY clause OR be using an aggregator on the SELECT clause. ● Aggregators: ● ANY_VALUE() ● MIN() ● MAX() ● SUM() ● COUNT()
  • 43. @gabidavila MySQL `sys` schema ● Needs to be installed on 5.6 ● Installed by default on 5.7 ● MySQL Workbench 6.3 ships with a client for it ● If enabled, in production should be used for critical analytical cases
  • 45. @gabidavila What can I do with it? *High Cost SQL statements select * from sys.`x$statement_analysis` Top 5% slower queries select * from sys.`x$statements_with_runtimes_in_95th_percentile` Use temporary tables select * from sys.`statements_with_temp_tables` Unused Indexes select * from sys.`schema_unused_indexes` Full table scans select * from sys.`schema_tables_with_full_table_scans` *x$ is actually a view duplicated from a table with a more user friendly format
  • 48. @gabidavila Changes on 5.7 ● Passwords can now have expiration date ● NO_ZERO_DATE, NO_ZERO_IN_DATE, ERROR_FOR_DIVISION_BY_ZERO are deprecated and being default in STRICT mode in future versions ● Triggers now supports more than one event per table ● YEAR(2) was deprecated on 5.6, removed on 5.7
  • 49. @gabidavila Thank you! ● Twitter: @gabidavila ● Blog: http://gabriela.io ● Freenode: gabidavila ● Feedback: https://joind.in/talk/18d42 ● References: MySQL documentation