Вы находитесь на странице: 1из 127

Table

of Contents
Introduction 1.1
MySQL Architecture 1.2
Client\/Server Overview 1.2.1
Communication Protocols 1.2.2
Connecting to MySQL Server 1.2.3
The SQL Parser and Storage Engines 1.2.4
How MySQL uses Disk Space 1.2.5
How MySQL Uses Memory 1.2.6
Monitoring MySQL Memory Usage 1.2.7
System Administration 1.3
Types of MySQL Distributions 1.3.1
Starting and Stopping MySQL Server on Unix 1.3.2
Runtime Configuration 1.3.3
Loading Timezone Tables 1.3.4
Setting Default SQL Mode 1.3.5
Upgrading MySQL Server 1.3.6
Client Programs for DBA Work 1.4
MySQL WorkBench 1.4.1
Command Line Clients 1.4.2
mysqladmin - Client for Administering a MySQL Server 1.4.3
mysqlcheck - A Table Maintenance Program 1.4.4
mysqldump - A Database Backup Program 1.4.5
mysqlimport - A Data Import Program 1.4.6
mysqlshow - Display Database, Table, and Column Information 1.4.7
mysqlslap - Load Emulation Client 1.4.8
MySQL Workbench 1.5
User Management 1.6

1
Data Types 1.7
Character Set Support 1.7.1
Transactions and Locking 1.8
Locking Concepts 1.8.1
Advisory Locks 1.8.2
Obtaining Metadata 1.9
Storage Engines 1.10
MySQL Storage Engines Overview 1.10.1
MyISAM Storage Engine 1.10.2
InnoDB Storage Engine 1.10.3
InnoDB Memcached Storage Plugin 1.10.4
Memory Engine 1.10.5
Federated Engine 1.10.6
Partitioning 1.11
Why Partition 1.11.1
Types of Partitioning 1.11.2
Creating Partitioned Tables 1.11.3
Obtaining Partition Metadata 1.11.4
Security 1.12
Table Maintenance 1.13
Exporting and Importing Data 1.14
Programming inside MySQL 1.15
MySQL Backup and Recovery 1.16
Replication 1.17
Setting Master Server 1.17.1
Setting Up Replication on the Salve Database 1.17.2
Introduction to Performance Tuning 1.18
Index Types 1.18.1
Clustered Index 1.18.2
Secondary Index 1.18.3

2
Basic Indexing 1.18.4
Order of Indexes 1.18.5
OR Conditional with Indexes 1.18.6

3
Introduction

MySQL 5.6 Database Administration


Certification Guide
This file file serves as your book's preface, a great place to describe your book's
content and ideas.

4
MySQL Architecture

MySQL Architecture
1. The client\/server architectural design of MySQL

2. Communication protocols that clients can use to connect to the server

3. The relationship between the server's storage engines and its SQL parser
and optimizer

4. The SQL Layer

5. The Storage Layer

6. How the server supports storage engines

7. How MySQL uses memory and disk space

8. The MySQL plugi-in interface

5
Client\/Server Overview

Client Server Overview


The MySQL database system operates using a client\/server architecture.

MySQL Server
The mysqld program is the MySQL server database program that manages the
database and tables.

Client Programs
Client programs communicate with the server by sending request over a network
connection. Examples of client programs are mysql and mysqladmin

Non-client utility programs


These programs are used for special purposes and do not act as clients of the
server. Examples are mysql_safe , myisamchk

6
Communication Protocols

Communication Protocols
MySQL supports different types of connections from the client to the server.

Protocol Type of connection Supported operating systems


TCP\/IP Local\/remote All
Unix socket file Local Unix
Named pipes Local Windows
Shared memory Local Windows

Disabling TCP\/IP
TCP\/IP can be disabled by using the start-up option passed to the mysqld
command line --skip-networking .

TCP\/IP networking can also be disable in the my.cnf config file

[mysqld]
skip-networking

Named Pipes
Names pipes are disabled by default and can be enabled by using the - -enable-
named-pipe option

Shared Memory
Shared memory is disabled by default and can be enabled by using the startup
option --shared-memory

7
Connecting to MySQL Server

Connecting to MySQL Server


To establish a connection to a MySQL server you can use the command line
mysql client program.

Connecting without passwing options

$ mysql

Because the are no parameter options, the default values apply :

The default hostname is localhost. On Unix use a socket connection

The default user is ODBC on Windows

The default user is the login name on Unix

No password is sent if neither - p nor --password is given

Specify hostname and username

$ mysql --host=localhost --user=root --password=mypassword datab


ase

For password options, the password is optional:

If you specifiy a -p or --password option and specify a password value, there


must be no space between -p or --password .

If you use -p or --password option but do not specify the password value,
the client program prompts to enter the passowrd. This is the recommend option.
The password is not displayed as you ente it.

Not specifiying the password option

8
Connecting to MySQL Server

$ mysql --host=localhost --user=root --password database

is equivalent to

$ mysql -h localhost -u root -p database

Connect with TCP\/IP on Unix


By default on Unix, mysql connects using the socket by default. To use TCP\/IP
specify the host or ip address or specifiy the protocol

Specify the hostname

$ mysql -h localhost -u root -p database

or specify the protocol

$ mysql --protocol tcp -u root -p database

Process lsit when logged in using Unix Socket

Process List when logged in with TCP\/IP option

9
Connecting to MySQL Server

10
The SQL Parser and Storage Engines

The SQL Parser and Storage Engine Tiers

The MySQL server executes SQL statements independent of the storage engines.
The server executes each statement using a two-tier model :

The upper tier includes the SQL parser and optimizer. The tier does not
interact with the tables directly

The lower tier comprises of a set of storage engines. The engines are used
for managging tables of a particular type. The storage engine associated with
a table directly accesses it to store or retrieve data.

11
How MySQL uses Disk Space

How MySQL Uses Disk Space

Data Directories
MySQL stores the location to the folder containing the database in the variable
called datadir and the binaries in basedir .

mysql> show variables where variable_name in ('datadir', 'basedi


r');
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| basedir | /usr |
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
2 rows in set (0.00 sec)

Database Folder
Each database corresponds to a single folder under the datadir variable value
regardless of what tables you created. The database is storage engine
independent. One database can contain tables with different storage engines.

mysql , test and performance_schema are folders for each individual


database.

12
How MySQL uses Disk Space

root@ubuntu:/var/lib/mysql# ls -l
total 122912
-rw-r----- 1 mysql mysql 56 Aug 11 11:19 auto.cnf
-rw-r--r-- 1 root root 0 Aug 11 11:19 debian-5.7.flag
-rw-r----- 1 mysql mysql 291 Aug 11 16:11 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 Aug 11 17:28 ibdata1
-rw-r----- 1 mysql mysql 50331648 Aug 11 17:28 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Aug 11 11:19 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 Aug 11 16:11 ibtmp1
drwxr-x--- 2 mysql mysql 4096 Aug 11 11:19 mysql
drwxr-x--- 2 mysql mysql 4096 Aug 11 11:19 performance_schema
drwxr-x--- 2 mysql mysql 12288 Aug 11 11:19 sys

Lets create test database.

mysql> create database test;

Check the file system in the /var/lib/mysql folder and notice the test directory
created for the test database.

root@ubuntu:/var/lib/mysql# pwd
/var/lib/mysql
root@ubuntu:/var/lib/mysql# ls -l
-rw-r----- 1 mysql mysql 414 Aug 11 11:19 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 Aug 11 11:19 ibdata1
-rw-r----- 1 mysql mysql 50331648 Aug 11 11:19 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Aug 11 11:19 ib_logfile1
-rw-r----- 1 mysql mysql 12582912 Aug 11 11:19 ibtmp1
drwxr-x--- 2 mysql mysql 4096 Aug 11 11:19 mysql
drwxr-x--- 2 mysql mysql 4096 Aug 11 11:19 performance_schema
drwxr-x--- 2 mysql mysql 12288 Aug 11 11:19 sys
drwxr-x--- 2 mysql mysql 4096 Aug 11 15:40 test

Tables
A table format file (.frm) is created for each table regardless of the
storage engine. The file are placed under the specific database folder.

13
How MySQL uses Disk Space

MyISAM creates a .myd for for stroing the table data and .myi for indexes.

InnoDB stores the data in a tablespace or in a .ibd if the server option


innodb_file_per_table is on .

InnoDB Storage Engine Files


The InnoDB storage engine uses tablespaces and logfiles. The tablespace
contains data and index information for all InnoDB tables. If the
innodb_file_per_table is on, each table which contain its own data in its onw
tablespace.

mysql> create table person (first_name varchar(50) primary key)


engine=innodb;Query OK, 0 rows affected (0.01 sec)

Check the filesystem and notice the person.ibd tablespace created for the
person table.

root@ubuntu:/var/lib/mysql/test# ls -l
total 112
-rw-r----- 1 mysql mysql 65 Aug 11 17:27 db.opt
-rw-r----- 1 mysql mysql 8572 Aug 11 17:28 person.frm
-rw-r----- 1 mysql mysql 98304 Aug 11 17:28 person.ibd

The default tablespace name is ibdata1 and the default log files are named
ib_logfile0 and ib_logfile1 .

MySQL Server Logs


By default no logs are enabled, except the error log on Windows.

14
How MySQL uses Disk Space

Log Type Information Written to Log


Problems encountered starting, running, or stopping
Error Log
mysqld
Established client connections and statements received
General query log
from clients
Relay log Data changes received from a replication master server
Binary log DStatements that change data(also used for replication)
Queries that took more than long_query_time
Slow query log
seconds to execute

DDL
Metadata operations performed by DDL statements
log(metadata log)

The General Query Log


Established client connections and statements received from clients .

mysql> show variables like 'general%';


+------------------+---------------------------+
| Variable_name | Value |
+------------------+---------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/ubuntu.log |
+------------------+---------------------------+
2 rows in set (0.00 sec)

The Binary Log


The binary log contains "events" that describe database changes such as table
creation operations or changes to table data. The binary log is not used for
statements such as SELECT or SHOW that do not modify data. Only complete
transactions are logged.

15
How MySQL uses Disk Space

mysql> show variables like 'log_bin';


+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | OFF |
+---------------+-------+
1 row in set (0.00 sec)

The Slow Query Log


The slow query log contains SQL statements that took more than
long_query_time seconds to execute and required at least
min_examined_row_limit rows to be examined. The minimum and default
values of long_query_time are 0 and 10, respectively.

mysql> show variables like 'slow_query%';


+---------------------+--------------------------------+
| Variable_name | Value |
+---------------------+--------------------------------+
| slow_query_log | OFF |
| slow_query_log_file | /var/lib/mysql/ubuntu-slow.log |
+---------------------+--------------------------------+
2 rows in set (0.01 sec)

Administrative queries and queries without using indexes are not logged.

mysql> show variables where variable_name in ('log_slow_admin_st


atements', 'log_queries_not_using_indexes');
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | OFF |
| log_slow_admin_statements | OFF |
+-------------------------------+-------+
2 rows in set (0.00 sec)

16
How MySQL uses Disk Space

The DDL Log


Records metadata operations generated by data definition statements such as
DROP TABLE and ALTER TABLE . MySQL uses this log to recover from crashes
occuring in the middle of a metadata operation. The log file file is kept under the
data directory with the file name dd_log.log

17
How MySQL Uses Memory

How MySQL Uses Memory


The server allocates memory for many kinds of caches and buffers :

Buffer Pool
The memory area where InnoDB caches data and indexes. The default value is
128MB. The value is set using the innodb_buffer_pool_size .

mysql> show variables like 'innodb_buffer_pool_size';


+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+

You can also see the status of the InnoDB buffer pool and memory usage.

mysql> show engine innodb status ;

Check memory usage under the section BUFFER POOL AND MEMORY

18
How MySQL Uses Memory

BUFFER POOL AND MEMORY


----------------------
Total large memory allocated 137428992
Dictionary memory allocated 422961
Buffer pool size 8192
Free buffers 7901
Database pages 291
Old database pages 0
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 250, created 41, written 69
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random r
ead ahead 0.00/s
LRU len: 291, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

On a dedicated server, you can set the pool size to 80% of the machine's physical
memory. The buffer pool size can be set dynamically as of MySQL 5.7.5 without
restarting the server.

MySQL Performance Schema


Is a feature for monitoring MySQL server execution at a low level. The
Performance Schema dynamically allocates memory incrementally, scaling
memory use to actual server load, instead of allocating required memory during
server startup. Once memory is allocated it is not free until the server is restared.

Client Connections Threads


Each thread that is used to manage client connections uses some thread-specific
space :

19
How MySQL Uses Memory

Thread Stack
The stack for each thread. The default siaze is 192KB(256KB for 64-bit systems).
The stack is large enough for normal operations. If the thread stack is too small, it
limits the complexity of the SQL statements that the server can handle, the
recursion depth of stored procedures.

mysql> show variables where variable_name = 'thread_stack';


+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| thread_stack | 196608 |
+---------------+--------+

Connection and Result Buffers


Each client thread is associated with a connection buffer and result buffer. Both
begin with a given size by net_buffer_length but are dynamically enlarged to
max_allowed_packet bytes as needed.

mysql> show variables like 'net_buffer_length';


+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| net_buffer_length | 16384 |
+-------------------+-------+

MyISAM Key Buffer


The index blocks for the MyISAM tables are buffered and shared by all thread.
The key_buffer_size is the size of the buffer used for index blocks.

Temporary Tables

20
How MySQL Uses Memory

Most temporary tables memory-based hash tables. If an internal in-memory table


becomes too large, MySQL handles this automatically by changing the table from
in-memory disk format, handled by the storage engine defined by
internal_tmp_disk_storage_engine .

mysql> show variables like 'internal_tmp_disk_storage_engine';


+----------------------------------+--------+
| Variable_name | Value |
+----------------------------------+--------+
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+

Memory Storage Engine


Tables explicitly created with CREATE TABLE , only the max_heap_table_size
determines how large the table is permitted to grow and there is no conversion to
on-disk format.

Grant Tables
The grant tables store information about MySQL user accounts and privileges
they have. The server loads a copy of the grant tables in memory for fast access.
The memory is not released and can only be freed by FLUSH PRIVILEGES .

Open Tables
A tabke cache holds descriptors of open tables. For frequently used tables,
keeping the descriptors in memory avoids having to open the again and again.

mysqladmin status shows the number of open tables.

root@ubuntu:/var/lib/mysql# mysqladmin -u joseph -p status


Enter password:
Uptime: 52024 Threads: 2 Questions: 243 Slow queries: 0 Opens: 2
57 Flush tables: 1 Open tables: 98 Queries per second avg: 0.004

21
How MySQL Uses Memory

or from the global system variables

mysql> show global status like 'Open_tables';


+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 99 |
+---------------+-------+

22
Monitoring MySQL Memory Usage

Monitoring MySQL Memory Usage


You can monitor MySQL memory usage using the Performance Schema and
sys schema .

By default the instrumentation is disabled. Instruments can can be enabled by


updating the ENABLED column of the Performance Schema
setup_instruments table. Memory insturments have names in the form of
memory/code_area/instrument_name\ where code_area is a value such as
`sql` or innodb and instruments_name is the instrument detail.

mysql> SELECT * FROM performance_schema.setup_instruments WHERE


NAME LIKE '%memory%';
+---------------------------------------------------------------
-----------------+---------+-------+
| NAME | ENABLED | TIMED |
+---------------------------------------------------------------
-----------------+---------+-------+
| memory/performance_schema/mutex_instances | YES | NO |
| memory/performance_schema/rwlock_instances | YES | NO |
| memory/performance_schema/cond_instances | YES | NO |
| memory/performance_schema/file_instances | YES | NO |
| memory/performance_schema/socket_instances | YES | NO |
| memory/performance_schema/metadata_locks | YES | NO |
| memory/performance_schema/file_handle | YES | NO |
| memory/performance_schema/accounts | YES | NO |

Enabling Instruments
To enable all memory instruments, add the following line to the my.cnf config file :

[mysqld]
performance-schema-instrument='memory/%=COUNTED'

InnoDB Buffer Pool Memory Used

23
Monitoring MySQL Memory Usage

Show the memory used by the InnoDB buffer pool

mysql> SELECT * FROM performance_schema.memory_summary_global_by


_event_name WHERE EVENT_NAME LIKE 'memory/innodb/buf_buf_pool'\G
*************************** 1. row ***************************
EVENT_NAME: memory/innodb/buf_buf_pool
COUNT_ALLOC: 1
COUNT_FREE: 0
SUM_NUMBER_OF_BYTES_ALLOC: 137428992
SUM_NUMBER_OF_BYTES_FREE: 0
LOW_COUNT_USED: 0
CURRENT_COUNT_USED: 1
HIGH_COUNT_USED: 1
LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 137428992
HIGH_NUMBER_OF_BYTES_USED: 137428992

sys Schema Memory Usage


We can obtain the above information using the sys schema
memory_global_by_current_bytes

mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE ev


ent_name LIKE 'memory/innodb/buf_buf_pool'\G
*************************** 1. row ***************************
event_name: memory/innodb/buf_buf_pool
current_count: 1
current_alloc: 131.06 MiB
current_avg_alloc: 131.06 MiB
high_count: 1
high_alloc: 131.06 MiB
high_avg_alloc: 131.06 MiB

Currently Allocated Memory

24
Monitoring MySQL Memory Usage

mysql> select * from x$memory_global_total;


+-----------------+
| total_allocated |
+-----------------+
| 321167937 |
+-----------------+

By Code Area

mysql> SELECT SUBSTRING_INDEX(event_name,'/',2) AS


-> code_area, sys.format_bytes(SUM(current_alloc))
-> AS current_alloc
-> FROM sys.x$memory_global_by_current_bytes
-> GROUP BY SUBSTRING_INDEX(event_name,'/',2)
-> ORDER BY SUM(current_alloc) DESC;
+---------------------------+---------------+
| code_area | current_alloc |
+---------------------------+---------------+
| memory/innodb | 180.80 MiB |
| memory/performance_schema | 90.35 MiB |
| memory/sql | 18.86 MiB |
| memory/mysys | 16.27 MiB |
| memory/memory | 213.15 KiB |
| memory/myisam | 34.98 KiB |
| memory/blackhole | 512 bytes |
| memory/csv | 512 bytes |
+---------------------------+---------------+

25
System Administration

System Administration
1. Types of MySQL distributions

2. Installing MySQL Server

3. Starting and stopping MySQL Server

4. Running multiple MySQL servers on a single host

5. Specifying options for server runtime configuration

6. Log and status files

7. Loading the time zone tables for named time zone support

8. Security-related configurations options

9. Setting the default sql-mode

10. Upgrading an older installation to a newer version of MySQL

26
Types of MySQL Distributions

Type of MySQL Distributions


MySQL is available for Windows and Unix operating systems. MySQL can be
installed from pre-compiled binaries and from source files.

27
Starting and Stopping MySQL Server on Unix

Starting and Stopping MySQL on Unix


MySQL runs as the user mysql abd the server process is called mysqld.

joseph@ubuntu:~$ ps ax | grep mysqld


4477 pts/4 S+ 0:00 grep --color=auto mysqld
31065 ? Ssl 0:01 /usr/sbin/mysqld

when using binary installations MySQL can be started and stopped with the
startup scripts in /etc/init.d

Start MySQL

joseph@ubuntu:~$ sudo service mysql start

Stopping MySQL

joseph@ubuntu:~$ sudo service mysql stop

or using the mysqladmin shutdown

joseph@ubuntu:~$ mysqladmin -u joseph -p shutdown

Check Status

28
Starting and Stopping MySQL Server on Unix

joseph@ubuntu:~$ sudo service mysql status


● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; ven
dor preset: enabled)
Active: active (running) since Fri 2016-08-12 07:34:18 CAT; 35s
ago
Process: 5110 ExecStartPost=/usr/share/mysql/mysql-systemd-star
t post (code=exited, status=0/SUCCESS)
Process: 5105 ExecStartPre=/usr/share/mysql/mysql-systemd-start
pre (code=exited, status=0/SUCCESS)
Main PID: 5109 (mysqld)
Tasks: 28 (limit: 512)
CGroup: /system.slice/mysql.service
└─5109 /usr/sbin/mysqld

Aug 12 07:34:17 ubuntu systemd[1]: Starting MySQL Community Serv


er...
Aug 12 07:34:18 ubuntu systemd[1]: Started MySQL Community Serve
r.

29
Runtime Configuration

Runtime Configuration
The MySQL server maintains sytem variables that indicate how it is configured.
Each system variable has a default value. System variables can be set at server
startup using options on the command line or in an options file.

The server maintains two kinds of variables.

Global variables affect the overall operation of the server.


Session variables affect its operation for individual connections. A given
system variable can have both a global and session value.

Some system variables can be dynamically changed whilst the system is running
by using the SET statement without having to stop and restart the server.

Setting variables on the command line

mysqld --query_cache_size=16M --max_allowed_packet=1G

Setting variables in the options in the

[mysqld]
query_cache_size=16M
max_allowed_packet=1G

Restrict maximum value of system variable


You can prefix the keyword --maximum to specify the maximum value the variable
can be set to e.g to restrict the query cache being set above 32M.

mysqld --query_cache_size=16M --maximum-query-cache-size=32M

30
Runtime Configuration

Show compiled-in defaults plus values read from


options file

mysqld --verbose --help

Show compiled-in defaults, ignoring settings in


options file

mysqld --no-defaults --verbose --help

Show current values used by a running server

mysql> show variables;

or using mysqladmin variables on the terminal

joseph@ubuntu:~$ mysqladmin -u joseph -p variables

Dynamic System Variables


Dynamic system variables can be set at runtime using SET GLOBAL/SET
@@GLOBAL.variable_name or SET SESSION/SET @@SESSION.variable_name .

Show global variable state


You can use the SELECT statement with @@global to show the value of the
variable

31
Runtime Configuration

mysql> select @@global.query_cache_size;


+---------------------------+
| @@global.query_cache_size |
+---------------------------+
| 16777216 |
+---------------------------+

Some variables are not available as SESSION variaables and will give an error

mysql> select @@session.query_cache_size;


ERROR 1238 (HY000): Variable 'query_cache_size' is a GLOBAL vari
able

Selecting session variables


Use the @@session to show the session variable

mysql> select @@session.max_join_size;


+-------------------------+
| @@session.max_join_size |
+-------------------------+
| 18446744073709551615 |
+-------------------------+

Setting Variables
You can use the SET statment with scope of either GLOBAL or SESSION to set
the value of the variable

mysql> set global max_allowed_packet=16*1024*1024;


Query OK, 0 rows affected (0.01 sec)

Using the qualify of K for Kilobytes, M for megabytes or G for Gigabytes is not
allowed when setting value during runtime

32
Runtime Configuration

mysql> set global max_allowed_packet=16M;


ERROR 1232 (42000): Incorrect argument type to variable 'max_all
owed_packet'

During server starup the qualifies are allowed

joseph@ubuntu:~$ mysql --max_allowed_packet=24M


Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.13-0ubuntu0.16.04.2 (Ubuntu

Setting the values to default


You can set the variables back to their defaults

mysql> set global max_allowed_packet=DEFAULT;


Query OK, 0 rows affected (0.00 sec)

and checking again, the max_allowed_packet has been reset to the default.
The value will persist as long the server has not been restarted.

mysql> select @@global.max_allowed_packet;


+-----------------------------+
| @@global.max_allowed_packet |
+-----------------------------+
| 4194304 |
+-----------------------------+

Setting true\/false values


Some system variables can be enabled with the SET statement by setting them
to ON or 1 , or disabled by setting them to OFF or 0 .

However, to set such a variable on the command line or in an option file, you must
set it to 1 or 0 , setting it to ON or OFF will not work.

33
Runtime Configuration

Using SHOW statement


To display system variable names and values use the the SHOW VARIABLES
statments.

mysql> show variables;

By default the SHOW statement displays session variables. Use SHOW GLOBAL
to show global variables

mysql> show global variables;

Filter Results of SHOW VARIABLES with LIKE


Use the like to filter the result of the SHOW VARIABLES

mysql> show variables like 'max_connections';


+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+

and you can also use wildcards like _ for a single character and % any character

34
Runtime Configuration

mysql> show variables like '%cache%';


+--------------------------------+----------------------+
| Variable_name | Value |
+--------------------------------+----------------------+
| binlog_cache_size | 32768 |
| have_query_cache | YES |
| host_cache_size | 279 |
| innodb_disable_sort_file_cache | OFF |
| innodb_ft_cache_size | 8000000 |
| query_cache_wlock_invalidate | OFF |
| stored_program_cache | 256 |
| table_definition_cache | 615 |
| table_open_cache | 431 |
+--------------------------------+----------------------+

or altenative use a WHERE clause

mysql> show variables where variable_name = 'query_cache_size';


+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| query_cache_size | 16777216 |
+------------------+----------+

35
Loading Timezone Tables

Loading Timezone Tables


The server uses the time zone tables to implement support for named times such
as 'Africa\/Johannesburg'.However the time zone tables are created as empty
tables, which means that, by default, named time zones cannot be used. To
enable this capability, you must load the tables.

mysql> use mysql

Check the time_zone table and you will notice its empty

mysql> select * from time_zone;


Empty set (0.00 sec)

On Unix you can find the system time zone files located in
/usr/share/zoneinfo . These files needs to be converted into a format that
can be located into MySQL.

joseph@ubuntu:/usr/share/zoneinfo$ ls -l
total 324
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Africa
drwxr-xr-x 6 root root 20480 Jul 17 18:49 America
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Antarctica
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Arctic
drwxr-xr-x 2 root root 12288 Jul 17 18:49 Asia
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Atlantic
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Australia
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Brazil
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Canada
drwxr-xr-x 2 root root 4096 Jul 17 18:49 Chile

Convert system time zone to MySQL


statements

36
Loading Timezone Tables

Use the mysql_tzinfo_to_sql command line tool

$ mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql mysql

and checking again after executing the above

mysql> select * from time_zone;


+--------------+------------------+
| Time_zone_id | Use_leap_seconds |
+--------------+------------------+
| 1 | N |

and from the time_zone_name table

mysql> select * from time_zone_name;


+----------------------------------------+--------------+
| Name | Time_zone_id |
+----------------------------------------+--------------+
| Africa/Abidjan | 1 |
| Africa/Accra | 2 |
| Africa/Addis_Ababa | 3 |

Note - You might need to restart the server touse the new time zone data.

Windows distriution comes preloaded with the time zone tables as it does not
support time zone files for the operating system.

37
Setting Default SQL Mode

Setting the Default SQL Mode


Server SQL modes define what SQL syntax MySQL should support and what kind
of of data validation checks should it perform. This makes it easier to MySQL in
different environments and touse MySQL togehter with other database servers.
The MySQL Server apply these modes individually to different cleints.

Default SQL mode for MySQL 5.7

mysql> select @@global.sql_mode;


+---------------------------------------------------------------
----------------------------------------------------------------
------------+
| @@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_S
UBSTITUTION |
+---------------------------------------------------------------
----------------------------------------------------------------
------------+

Setting the SQL Mode


The mode can be set on the command line

$ mysqld --sql-mode="TRADITIONAL"

or in the option file

[mysqld]
sql-mode=TRADITIONAL

38
Setting Default SQL Mode

Change Mode during Runtime


For the session

SET SESSION sql_mode = 'modes';

or for the whole server

SET GLOBAL sql_mode = 'modes';

Important Modes
ANSI DB2 MAXDB MYSQL323 MYSQL40 ORACLE POSTGRESQL
TRADITIONAL

39
Upgrading MySQL Server

Upgrading MySQL

Supported Upgrade Methods

In-place upgrade
Involves shutting down the old MySQL version, replacing the old MySQL binaries
or packages with the new ones, restarting MySQL on the existing data directory,
and running mysql_upgrade .

Logical Upgrade
Involves exporting existing data from the old MySQL version using mysqldump ,
installing the new MySQL version, loading the dump file into the new MySQL
version, and running mysql_upgrade

Performing an In-place Upgrade


Backup the databases before you begin and read the upgrade notes for the
specific version.

1. Configure MySQL to perform a slow shutdown by setting


innodb_fast_shutdown to 0 . shell> bin/mysql -u root -p
password --execute="set global innodb_fast_shutdown=0"

2. Shut down the old MySQL server shell> bin/mysqladmin -u root -p


password shutdown

3. Upgrade the MySQL binaries or packages in place, replacing the old binaries
or packages with the new ones.

4. Start the MySQL server, using the existing data directory.

5. Run mysql_upgrade .

40
Upgrading MySQL Server

Performing a Logical Upgrade


1. Export your existing data from the previous MySQL version: shell>
mysqldump --add-drop-table --routines --events -> --all-
databases --force > data-for-upgrade.sql

2. Shut down the old MySQL server shell> bin/mysqladmin -u root -p


password shutdown

3. Install MySQL 5.7.

4. Initialize a new data directory shell> mysqld --initialize --


datadir=/path/to/5.7-datadir Copy the temporary 'root'@'localhost'
password printed to your screen or written to your error log for later use.

5. Start the MySQL 5.7 server, using the new data directory. shell>
bin/mysqld_safe --user=mysql --datadir=/path/to/5.7-datadir

6. Reset the root password shell> mysql -u root -p Enter


password: ** <- enter temporary root password

mysql> ALTER USER USER() IDENTIFIED BY 'your new password';

7. Load the previously created dump file into the new MySQL server. shell>
bin/mysql -u root -p password --execute="source data-for-
upgrade.sql" --force

8. Run mysql_upgrade. shell> bin/mysql_upgrade -u root -p password

9. Configure MySQL to perform a slow shutdown by setting


innodb_fast_shutdown to 0. shell> bin/mysql -u root -p password --
execute="set global innodb_fast_shutdown=0"

10. Shut down and restart the MySQL server to ensure a clean shutdown and
startup. shell> bin/mysqladmin -u root -p password shutdown
shell> bin/mysqld_safe --user=mysql --datadir=/path/to/5.7-
datadir

41
Client Programs for DBA Work

Client and Utility Programs for DBA Work


1. MySQL Workbench graphical client

2. The mysql

3. The mysqladmin command-line client

4. The mysqlimport command-line tool

5. The mysqldump command-line tool

6. The mysqlcheck command-line tool

7. The myisamchk command-line tool

8. The mysqlhotcopy command-line tool

9. innochecksum — Offline InnoDB File Checksum Utility

10. myisam_ftdump — Display Full-Text Index information

11. myisamchk — MyISAM Table-Maintenance Utility

12. myisamlog — Display MyISAM Log File Contents

13. myisampack — Generate Compressed, Read-Only MyISAM Tables

14. mysql_config_editor — MySQL Configuration Utility

15. mysqlbinlog — Utility for Processing Binary Log Files

16. mysqldumpslow — Summarize Slow Query Log Files

17. Available APIs and drivers and connectors

42
MySQL WorkBench

MySQL Workbench
MySQL is a graphical client for easier management of a MySQL database.

43
Command Line Clients

Command Line Clients - mysql

mysql
Is a simple shell with input line editing capabilites. It supports interactive and
noninteractive use. Whe used interactively,q query results are presented in an
ASCII-table format.

Using the myql

joseph@ubuntu:~$ mysql

or with options

shell> mysql --user=user_name --password=your_password db_name

Or execute statments from a script file

shell> mysql db_name < script.sql

44
mysqladmin - Client for Administering a MySQL Server

mysqladmin - Client for Administering a


MySQL Server
mysqladmin is a client for performing administrative operations. You can use it to
check the server's configuration and current status, to create and drop databases,
and more.

Check server status

joseph@ubuntu:~$ mysqladmin -u joseph -p status

or use the extended-status option

joseph@ubuntu:~$ mysqladmin -u joseph -p extended-status

Check runtime server variables

joseph@ubuntu:~$ mysqladmin -u joseph -p variables


Enter password:
+----------------------------------------------------------+----
--+
| Variable_name | Value |
+----------------------------------------------------------+----
--+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | ON

Shutdown the server

joseph@ubuntu:~$ mysqladmin -u joseph -p shutdown

45
mysqladmin - Client for Administering a MySQL Server

Show version of the server

joseph@ubuntu:~$ mysqladmin -u joseph -p version

Start replication on the slave

joseph@ubuntu:~$ mysqladmin -u joseph -p start-slave

Stop replication on the slave

joseph@ubuntu:~$ mysqladmin -u joseph -p stop-slave

Reload grant tables

joseph@ubuntu:~$ mysqladmin -u joseph -p reload

Flush all tables and close and open log files

joseph@ubuntu:~$ mysqladmin -u joseph -p refresh

Show a list of active threads(clients).

46
mysqladmin - Client for Administering a MySQL Server

joseph@ubuntu:~$ mysqladmin -u joseph -p processlist


Enter password:
+----+--------+-----------+-------+---------+------+----------+-
-----------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+--------+-----------+-------+---------+------+----------+-
-----------------+
| 5 | joseph | localhost | mysql | Sleep | 8299 | | |
| 21 | joseph | localhost | | Query | 0 | starting | show proces
slist |
+----+--------+-----------+-------+---------+------+----------+-
-----------------+

Change user password

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p password


Enter password:
New password:
Confirm new password:

Kill server thread(client)


First find the process id or pid

47
mysqladmin - Client for Administering a MySQL Server

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p processlist


Enter password:
+----+--------+-----------+-------+---------+------+----------+-
----------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+--------+-----------+-------+---------+------+----------+-
----------------------+
| 5 | joseph | localhost | mysql | Sleep | 8551 | | |
| 27 | joseph | localhost | | Query | 0 | starting | show full p
rocesslist |
+----+--------+-----------+-------+---------+------+----------+-
----------------------+

and then kill the process

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p kill 5

Reload grant privileges tables

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p flush-privile


ges

Flush log files

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p flush-logs

Flush all tables

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p flush-tables


Enter password:

notice, no more open tables after flushing the table cache

48
mysqladmin - Client for Administering a MySQL Server

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p status


Enter password:
Uptime: 13065 Threads: 2 Questions: 11773 Slow queries: 0 Opens:
745 Flush tables: 2 Open tables: 0 Queries per second avg: 0.90
1

Flush the thread cache

joseph@ubuntu:~$ mysqladmin --verbose -u joseph -p flush-threads

49
mysqlcheck - A Table Maintenance Program

mysqlcheck - A Table Maintenance Program

50
mysqldump - A Database Backup Program

mysqldump - A Database Backup Program

51
mysqlimport - A Data Import Program

mysqlimport - A Data Import Program

52
mysqlshow - Display Database, Table, and Column Information

mysqlshow - Display Database, Table, and Column Information

53
mysqlslap - Load Emulation Client

mysqlslap - Load Emulation Client

54
MySQL Workbench

MySQL Workbench
1. An overview of MySQL Workbench features

2. MySQL Workbench server monitoring capabilities

3. MySQL Workbench server configurastion capabilities

4. MySQL Workbench backup and restore capabilities

55
User Management

User Management
1. Requirements for user authentication

2. Using SHOW PROCELIST to show which threads are running

3. Creating, modifying and dropping user accounts

4. Alternative authentication plugins

5. Requirements for user authorizations

6. Levels fo access privileges for users

7. Types of privileges

8. Granting, modfying, and revoking user privileges

56
Data Types

Data Types
1. Major categories of data types

2. Meaning of NULL

3. Column attributes

4. Character set usage with data types

5. Choosing an appropriate data type

57
Character Set Support

Character Set Support What is Character Set A character set is a set of symbols
and encodings. Suppose that we have an alphabet with four letters: A, B, a,
b . We give each letter a number: A = 0, B = 1, a = 2, b = 3 . The letter
A is a symbol, the number 0 is the encoding for A , and the combination
of all four letters and their encodings is a character set .

What is a Collation A collation is a set of rules for comparing characters in a


character set.

MySQL includes character set support that enables you to store data using a
variety of character sets and perfrom comparisons according to a variety of
collations. You can specifiy character sets at the server, database, table and
column level. MySQL supports the use of character sets for the MyISAM,
MEMORY,a dn InnoDB storage engines.

Performance Issues

MySQL will need tobe compiled from the source to remove unnecessary character
sets.

Show available character sets

mysql> show character set;


+----------+---------------------------------+------------------
---+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+------------------
---+--------+
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
| dec8 | DEC West European | dec8_swedish_ci | 1 |
| cp850 | DOS West European | cp850_general_ci | 1 |
.................................other rows removed to save spac
e

Notice the length of the character set. utf8 requires 3 bytes per character.
So a column with CHAR(32) will require 96 bytes using utf8

Show available collations

58
Character Set Support

mysql> show collation;


+--------------------------+----------+-----+---------+---------
-+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+--------------------------+----------+-----+---------+---------
-+---------+
| big5_chinese_ci | big5 | 1 | Yes | Yes | 1 |
| big5_bin | big5 | 84 | | Yes | 1 |
............others removed to save space

or query from the information_schema database

mysql> select * from information_schema.CHARACTER_SETS;


+--------------------+----------------------+-------------------
--------------+--------+
| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION | MAXL
EN |
+--------------------+----------------------+-------------------
--------------+--------+
| big5 | big5_chinese_ci | Big5 Traditional Chinese | 2 |
| dec8 | dec8_swedish_ci | DEC West European | 1 |
| cp850 | cp850_general_ci | DOS West European | 1 |
| hp8 | hp8_english_ci | HP West European | 1 |
| koi8r | koi8r_general_ci | KOI8-R Relcom Russian | 1 |
........additional row removed

A given character set has at least one collation

59
Character Set Support

mysql> show collation where charset = 'latin1';


+-------------------+---------+----+---------+----------+-------
--+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+-------
--+
| latin1_german1_ci | latin1 | 5 | | Yes | 1 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
| latin1_danish_ci | latin1 | 15 | | Yes | 1 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 1 |
| latin1_general_ci | latin1 | 48 | | Yes | 1 |
| latin1_general_cs | latin1 | 49 | | Yes | 1 |
| latin1_spanish_ci | latin1 | 94 | | Yes | 1 |
+-------------------+---------+----+---------+----------+-------
--+

or query it from the information_schema database

mysql> select * from information_schema.collations where charact


er_set_name = 'utf8';
+--------------------------+--------------------+-----+---------
---+-------------+---------+
| COLLATION_NAME | CHARACTER_SET_NAME | ID | IS_DEFAULT | IS_COM
PILED | SORTLEN |
+--------------------------+--------------------+-----+---------
---+-------------+---------+
| utf8_general_ci | utf8 | 33 | Yes | Yes | 1 |
| utf8_bin | utf8 | 83 | | Yes | 1 |
| utf8_unicode_ci | utf8 | 192 | | Yes | 8 |
| utf8_icelandic_ci | utf8 | 193 | | Yes | 8 |
| utf8_latvian_ci | utf8 | 194 | | Yes | 8 |

Specifying a Character Set

Use the SET NAMES statement

mysql> SET NAMES 'utf8';

60
Character Set Support

Show Server Character Set mysql> show variables like 'character_set_server'; +--
--------------------+--------+ | Variable_name | Value | +----------------------+--------+ |
character_set_server | latin1 | +----------------------+--------+

Show Server Collation

mysql> show variables like 'collation_server';


+------------------+-------------------+
| Variable_name | Value |
+------------------+-------------------+
| collation_server | latin1_swedish_ci |
+------------------+-------------------+

Set Server Character Set You can specifiy the character set and collation during
startup

mysql> set @@global.character_set_server='latin2';


Query OK, 0 rows affected (0.00 sec)

and the character set have been changed

mysql> select @@character_set_server;


+------------------------+
| @@character_set_server |
+------------------------+
| latin2 |
+------------------------+

Database Character Set and Collation Every database has a character set and a
collation.

The CREATE DATABASE and ALTER DATABASE statements have optional


clauses for specifying the database character set and collation:

61
Character Set Support

CREATE DATABASE db_name


[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]

ALTER DATABASE db_name


[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]

Example for the test database

mysql> show create database test;


+----------+----------------------------------------------------
-------------+
| Database | Create Database |
+----------+----------------------------------------------------
-------------+
| test | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET l
atin1 */ |
+----------+----------------------------------------------------
-------------+
1 row in set (0.00 sec)

Show Database Collation and Character Set

mysql> select @@character_set_database, @@collation_database;


+--------------------------+----------------------+
| @@character_set_database | @@collation_database |
+--------------------------+----------------------+
| utf8 | utf8_general_ci |
+--------------------------+----------------------+

Table Character Set and Collation

Column Character and Collation

62
Transactions and Locking

Transactions and Locking


1. The ACID properties of transactions

2. Transaction isolation levels

3. Locking concepts

4. Using explicit table locks

5. Using advisory locks

63
Locking Concepts

Locking Concepts

Locking is a mechanism that prevents problems from occuring with simultaneous


data access by my multpile clients. Locks are managed by the server.

The effect of the locking mechanism is to serialize access to data so that when
multiple clients want to perform conflicting operations, each must wait its turn.

Not all types of concurrent access produce conlicts :

If a client wants to read data, other clients that want to read the same data do not
produce a conflict, and they all can read at the same time. A client that wants to
write must wait until the read has finside.

If a client wants to write data, all other clients must wait until the write has finished,
regardless of whether those clients want to read or write.

A reader must block writers, but not other readers\/ A writer must block both
readers and writers.

Acquiring Locks

A lock can be acquired implicitly or explicitly.

For a client that does nothing special to acquire locks, the MySQL Server impicitly
acquires locks as necessary to process the client's statmenets safely. For
example, the server acquires a read lock when the client issues a SELECT
statmenet.

Acquire Lock Explicitly

LOCK TABLES

mysql> lock tables person read;


Query OK, 0 rows affected (0.00 sec)

and check that the lock has been acquired, table shows its in use

64
Locking Concepts

mysql> show open tables where in_use = 1;


+----------+--------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+--------+--------+-------------+
| test | person | 1 | 0 |
+----------+--------+--------+-------------+

Unlock the tables

There's no need to pass in the table names. All the locks are realesed for the
current client.

mysql> unlock tables ;


Query OK, 0 rows affected (0.00 sec)

Explicity Lock Types

READ

Locks a table for reading. A READ lock locks a table for read quieries such as
SELECT that retrieve data from a table. It does not allow write operations such as
INSERT, DELETE, or UPDATE that modify the table, even by the client that holds
the lock.

WRITE

Locks a table for wiriting. A WRITE lock is an exclsive lock. Once acquired, only
the client holding the write lock can read from or write to the table. Other clients
can neither read from nor write to it.

READ LOCAL

Locks a table for reading, but allows concurrent inserts. Only applies to MyISAM
table. Insert will be appended at the end. Will not work if the table have holes,
(deletes inside the table).

LOW_PRIORITY_WRITE

65
Locking Concepts

Locks a table for writing, but acquires the lock with a lower priority.That is, if the
client must wait for the lock, other clients that request read locks during the wait
are allowed to get their lock first.

66
Advisory Locks

Advisory Locks Also called a cooperative lock. Advisory locks do not lock data and
they do not prevent access to data by clients except to the extent that they
cooperate with each other. Unlike implicit and explicit locks, advisory locks are not
managed by the server. Clients manage advisory lcoks using a set of function
calls to cooperate among themselves.

Acquire Lock Use the GET_LOCK() function

mysql> select get_lock('my_lock', 5);


+------------------------+
| get_lock('my_lock', 5) |
+------------------------+
| 1 |
+------------------------+

The first argument is the name ofbe locked, and the second the argument is the
timeout value in seconds that indicates hwo long to wait for the lock if it cannot be
acquired. Returns 1 for success, 0 if a timeout occured and the lock cannot be
acquired, NULL if an error occured.

Releasing Locks The lock is realesed by calling the RELEASE_LOCK() function or


by calling GET_LOCK() with the same name of when the client closes the
connection to the server.

mysql> select release_lock('my_lock');


+-------------------------+
| release_lock('my_lock') |
+-------------------------+
| 1 |
+-------------------------+

Check if a Lock is Free to Use The function IS_FREE_LOCK(lock_name) returns


1 if te name is not locked, 0 if it is locked, NULL if an error occurs.

67
Advisory Locks

mysql> select IS_FREE_LOCK('my_lock');


+-------------------------+
| IS_FREE_LOCK('my_lock') |
+-------------------------+
| 1 |
+-------------------------+

Check if a Lock is in Use

Use the function IS_USED_LOCK(lock_name)

mysql> select IS_USED_LOCK('my_lock');


+-------------------------+
| IS_USED_LOCK('my_lock') |
+-------------------------+
| NULL |
+-------------------------+

Return the connection id of the client that holds the lock on the name, or NULL if
the name is not locked.

68
Obtaining Metadata

Obtaining Metadata
1. Available metadata access methods

2. Using INFORMATION_SCHEMA compared to using SHOW statements

3. Syntax for accessing INFORMATION_SCHEMA

4. Limitation of INFORMATION_SCHEMA

5. The mysqlshow client program

69
Storage Engines

Storage Engines
1. An overview of storage engines in MySQL

2. InnoDB storage engine

3. InnoDB system and file-per-tablespaces

4. NoSQL and Memcached API

5. Configuring tablespaces efficiently

6. Using foregin keys to attain referential integrity

7. InnoDB locking

8. Features of available storage engines

9. MERGE storage engine

10. FEDERATED storage engine

11. MEMORY storage engine

12. MyISAM storage engine

70
MySQL Storage Engines Overview

MySQL Storage Engines

MySQL uses a pluggable architecture for the sotrage engines. Each table is
created using a specific storage engine.

Show Available Engines

mysql> show create table person;


+--------+------------------------------------------------------
----------------------------------------------------------------
------------+
| Table | Create Table |
+--------+------------------------------------------------------
----------------------------------------------------------------
------------+
| person | CREATE TABLE `person` (
`first_name` varchar(50) NOT NULL,
PRIMARY KEY (`first_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+--------+------------------------------------------------------
----------------------------------------------------------------
------------+

or use the SHOW TABLE statment

71
MySQL Storage Engines Overview

mysql> show table status;


+--------+--------+---------+------------+------+---------------
-+-------------+-----------------+--------------+-----------+---
-------------+---------------------+-------------+------------+-
------------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length |
Data_length | Max_data_length | Index_length | Data_free | Auto
_increment | Create_time | Update_time | Check_time | Collation
| Checksum | Create_options | Comment |
+--------+--------+---------+------------+------+---------------
-+-------------+-----------------+--------------+-----------+---
-------------+---------------------+-------------+------------+-
------------------+----------+----------------+---------+
| person | InnoDB | 10 | Dynamic | 0 | 0 | 16384 | 0 | 0 | 0 | N
ULL | 2016-08-11 17:28:19 | NULL | NULL | latin1_swedish_ci | NU
LL | | |
+--------+--------+---------+------------+------+---------------
-+-------------+-----------------+--------------+-----------+---
-------------+---------------------+-------------+------------+-
------------------+----------+----------------+---------+
1 row in set (0.00 sec)

or from the information_schema database

mysql>
mysql> select table_name, engine from information_schema.tables
where table_name = 'person';
+------------+--------+
| table_name | engine |
+------------+--------+
| person | InnoDB |
+------------+--------+
1 row in set (0.01 sec)

72
MyISAM Storage Engine

MyISAM Storage Engine

73
InnoDB Storage Engine

InnoDB Storage Engine

74
InnoDB Memcached Storage Plugin

InnoDB Memcached Plugin

75
Memory Engine

Memory Engine

76
Federated Engine

Federated Engine

77
Partitioning

Partitioning
1. Partitions and its use in MySQL

2. Reasons for using partitioning

3. Types of partitioning

4. Creating partitioned tables

5. Subpartitioning

6. Obtaining partition metadata

7. Modifying partitions to improve performance

8. Storage engine support of partitioning

78
Why Partition

Why Partition
Makes it possible to store more data in one table more than cab ne held on a
single disk or file system.
Easy to add and drop partitions.
Improves query performance by retrieving data from specific partitions using
a technique called partition pruning

Partitioning applies to all data and indexes of a table, you cannot partition only the
data and not the indexes, or vice versa, nor can you partion only a portion of the
table.

79
Types of Partitioning

Partion Types
Range
List
Columns
Hash
Key
Sub partitioning

Range Partitioning
A table that is partitioned by range is partitioned in such a way that each partition
contains rows for which the partitioning expression value lies within a given range.

Partition By The employees table by store_id

CREATE TABLE employees (


id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT NOT NULL, store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16),
PARTITION p3 VALUES LESS THAN (21)
);

or we can alternatively partition by store_id and have the other values that do
no match the partions go into a catch-all partition. We use the MAXVALUE to
specify all the other values.

80
Types of Partitioning

CREATE TABLE employees (


id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16),
PARTITION p3 VALUES LESS THAN MAXVALUE
);

Partition by time intervals


We can use time intervals to partiton the table. MySQL supports the following
functions when partitioning YEAR , TO_DAYS , TO_SECONDS .

CREATE TABLE members (


firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
PARTITION p0 VALUES LESS THAN (1960),
PARTITION p1 VALUES LESS THAN (1970),
PARTITION p2 VALUES LESS THAN (1980),
PARTITION p3 VALUES LESS THAN (1990),
PARTITION p4 VALUES LESS THAN MAXVALUE
);

or we can use the date columns on the table

81
Types of Partitioning

CREATE TABLE members (


firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
username VARCHAR(16) NOT NULL,
email VARCHAR(35),
joined DATE NOT NULL
)
PARTITION BY RANGE COLUMNS(joined) (
PARTITION p0 VALUES LESS THAN ('1960-01-01'),
PARTITION p1 VALUES LESS THAN ('1970-01-01'),
PARTITION p2 VALUES LESS THAN ('1980-01-01'),
PARTITION p3 VALUES LESS THAN ('1990-01-01'),
PARTITION p4 VALUES LESS THAN MAXVALUE );

List Partitioning Type


Same as RANGE partitioning type. The difference is each partition is defined and
selected based on the membership of column in one set of values.

CREATE TABLE test (


c1 INT,
c2 INT
)
PARTITION BY LIST (c1) (
PARTITION p0 VALUES IN (1, 4, 7),
PARTITION p1 VALUES IN (2, 5, 8)
);

If you try to insert values that are not within range, you will get an error.

Column Partitioning Type


This is a variant of the List and Range partioning types where columns are
used when partitioning values.

82
Types of Partitioning

CREATE TABLE employees_by_lname (


id INT NOT NULL, fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE COLUMNS (lname) (
PARTITION p0 VALUES LESS THAN ('g'),
PARTITION p1 VALUES LESS THAN ('m'),
PARTITION p2 VALUES LESS THAN ('t'),
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

or ALTER the table and partition the table.

ALTER TABLE employees


PARTITION BY RANGE COLUMNS (hired) (
PARTITION p0 VALUES LESS THAN ('1970-01-01'),
PARTITION p1 VALUES LESS THAN ('1980-01-01'),
PARTITION p2 VALUES LESS THAN ('1990-01-01'),
PARTITION p3 VALUES LESS THAN ('2000-01-01'),
PARTITION p4 VALUES LESS THAN ('2010-01-01'),
PARTITION p5 VALUES LESS THAN (MAXVALUE)
);

Hash Partitioning
Partitioning by HASH is used primarily to ensure an even distribution of data
among a predetermined number of partitions. MySQL takes care of calculating the
hash function for you.

83
Types of Partitioning

CREATE TABLE employees (


id INT NOT NULL, fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT, store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

or we can pass an SQL expression that returns an integer and MySQL will
calculate the hash for us.

CREATE TABLE employees (


id INT NOT NULL, fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT, store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

Key Partitioning Type


Partitioning by key is similar to partitioning by hash, except that where hash
partitioning employs a user-defined expression, the hashing function for key
partitioning is supplied by the MySQL server.

CREATE TABLE k1 (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;

84
Types of Partitioning

Sub Partitioning
Subpartitioning—also known as composite partitioning—is the further division of
each partition in a partitioned table.

85
Creating Partitioned Tables

Partitoning Tables

Check if partitioning is available

mysql> show plugins;

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

| Name | Status | Type | Library | License |

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

| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |


| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |

Or use the information_schema.plugins table

mysql> SELECT

-> PLUGIN_NAME as Name,

-> PLUGIN_VERSION as Version,

-> PLUGIN_STATUS as Status

-> FROM INFORMATION_SCHEMA.PLUGINS

-> WHERE PLUGIN_TYPE='STORAGE ENGINE';

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

| Name | Version | Status |

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

86
Creating Partitioned Tables

| binlog | 1.0 | ACTIVE |

| PERFORMANCE_SCHEMA | 0.1 | ACTIVE |

| MRG_MYISAM | 1.0 | ACTIVE |

| MEMORY | 1.0 | ACTIVE |

| InnoDB | 5.7 | ACTIVE |

| MyISAM | 1.0 | ACTIVE |

| CSV | 1.0 | ACTIVE |

| FEDERATED | 1.0 | DISABLED |

| partition | 1.0 | ACTIVE |

| BLACKHOLE | 1.0 | ACTIVE |

| ARCHIVE | 3.0 | ACTIVE |

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

87
Security

Security
1. Recognizing common security risks

2. Security risks specific to the MySQL installation

3. Security problems and counter measures for network, operating systems,


filsystems and users

4. Protecting your data

5. using SSL for secure MySQL server connections

6. How SSH enables a secure remote connection to the MySQL Server

88
Table Maintenance

Table Maintenance
1. Type of table maintenance operations

2. SQL statements for table maintenance

3. Client and utility programs for table maintenance

4. Repairing InnoDB tables

5. Maintaining tables for other storage engines

89
Exporting and Importing Data

Exporting and importing Data


1. Exporting Data

2. Importing Data

90
Programming inside MySQL

Programming MySQL
1. Creating and executing Stored Procedures

2. Describing stored routine execuition security

3. Creating and executing triggers

4. Creating, alerting and dropping events

5. Event execution scheduling

91
MySQL Backup and Recovery

MySQL Data Backup and Recovery


Methods
1. Types of backups

2. Backup tools and utilities

3. Making binary and text backups

4. The role of log and status files in backups

5. Performing data recovery

6. Using a replication slave for backups

92
Replication

Replication
1. Managing the MySQL binary log

2. MySQL replication threads and files

3. Setting up a MySQL Replication environment

4. Desigining complex replication topologies

5. Multi-Master and Cluster Replication

6. Performing a controlled switchover

7. Monitoring and troubleshooting replication

8. Replication with Global Transaction Identifiers(GTIDs)

93
Setting Master Server

Setting Replication on the Master

Setting Master Database


Enable binary logging. Replication requires that binrary logging is enabled.

Enable Binary Logging


Enable binary logging in the options file in /etc/mysql/my.cnf

[mysqld]
log_bin

Assign a master-id for the server


The server needs to have a master-id together with binary logging enabled to
work. If you enable binary logging and do not assign the master-id the server
will not start.

[mysqld]
master-id = 1

Usually you give the master id of 1 for the master database.

Enable Specific Database for Replication


By default the master will log all databases to the binary log. To enable only a
specific database for binary logging, use the binlog_do_db option.

[mysqld]
binlog_do_db = employees

94
Setting Master Server

Service is listening on an interface not


localhost
Make sure the server is reachable and TCP/IP is enabled.

mysql> show variables like 'bind_address';

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

| Variable_name | Value |

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

| bind_address | * |

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

Or should return an ip address not 127.0.0.1 . Replication does not use the
Unix socket, it requires TCP/IP.

Check skip_networking is OFF


Check if networking is enabled, the default value of skip_networking should
be OFF

mysql> show variables like '%networking%';

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

| Variable_name | Value |

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

| skip_networking | OFF |

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

95
Setting Master Server

Create a dedicated replication user account


This step is not necessary unless you want a separate use for replication. The
user needs to have the REPLICATION SLAVE privilege.

CREATE USER 'slave_user'@'%' identified by 'secure_password';

Grant permission for REPLICATION SLAVE

GRANT REPLICATION SLAVE ON *.* to 'slave_user'@'%';

Flush the privileges cache tables for the new login to take effect.

FLUSH PRIVILEGES;

Locking InnoDB tables to prevent writes


In order to take a successful database dump without corrupting the backup by
new writes, the database tables needs to be locked.

Change to the new database and lock the tables

use employees;
FLUSH TABLES WITH READ LOCK;

Record position of binary log


This is not necessary if we are going to use master auto position, but in case
record it.

Show the master status to find the position in the binary log

96
Setting Master Server

mysql> show master status;

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

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_G


tid_Set |

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

| master-bin.000008 | 154 | world, employees | | |

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

Record the position and take note of the name of the binary log.

Take a database dump of the databases;


There are several ways to take a dump of the database. For InnoDB, the
recommened way is to use a mysqldump .

ubuntu@master:~$ mysqldump --master-data -u root -p world > worl


d-backup.sql

with the --master-data option set, the mysqldump will write the the CHANGE
TO MASTER line in the dump file.

In my case in the world-backup.sql the statement was

CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000008', MASTER_LOG


_POS=154;

97
Setting Master Server

Unlock the Tables and Setup the Slave


Database

mysql> unlock tables;

98
Setting Up Replication on the Salve Database

Setting Replication on the Slave


Each server that participates in the replication setup needs to have a unique
server-id .

Setup server-id
Change the slave server server-id in the options file /etc/mysql/my.cnf

[mysqld]
server-id = 2

Restart the server for the option to take effect.

ubuntu@master:~$ sudo service mysql restart

Restore Database Backup


Restore the mysqldump file from the master server.

First create the database

mysql> create database employees;

On the shell, use mysqldump to do the restore

ubuntu@master:~$ mysqldump employees < employees.sql

Check if the slave_user can connect to master


try use the slave_user created in the previous step and connect to the master
database

99
Setting Up Replication on the Salve Database

ubuntu@slave-01:~$ mysql -u slave_user -h master -p

Enter password:

Welcome to the MySQL monitor. Commands end with ; or \g.

Setup the slave to point to the master


Use the CHANGE MASTER statement. Since we already provided the
MASTER_LOG_FILE and MASTER_LOG_POS we won't need to specificy them
here.

CHANGE MASTER TO
MASTER_HOST='master',
MASTER_USER='slave_user',
MASTER_PASSWORD='password';

or alternatively specificy more options

CHANGE MASTER TO
MASTER_HOST='master',
MASTER_USER='slave_user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='master-bin',
MASTER_LOG_POS=595;

100
Introduction to Performance Tuning

Introduction to Performance Tuning


1. Using EXPLAIN to analyze queries

2. General table optimizations

3. Monitoring status varaibles that affect performance

4. Setting and interpreting MySQL server variables

5. Overview of PERFORMANCE_SCHEMA

101
Index Types

Index Types

102
Clustered Index

Indexing for Performance

Types of Indexes

B-Tree Index
When you hear in the industry the word index, they often mean a B-tree index.
Most of the MySQL storage engine supports B-tree indexes. In B-tree index, each
leaf node contains a link to the next node for the fast range traversal. All the
values are stored in order and each leaf page is at the same distance from root
level.

B-Tree index is often referred as an index


Most storage engines support B+TreeIndexEach Leaf node contains a link to
the next node for the fast range traversals

Values are stored in order

Each leaf page is at the same distance from root level

InnoDBstorage uses B+TreeIndex

Advantages of B-Tree Index


B-Tree Index speeds up data access
Increase performance of following query patterns :
Full Value (e.g 'Jseph', 'Peruzal')
Leftmost Value or Colum Prefix (e.g 'Per' from 'Peruzal')
Range of Value (e.g from 1 to 99 or 'Joseph' to 'Prudence')
B-Tree supports helps ORDER BY clause to increase performance

Clustered Index for InnoDB

103
Clustered Index

Leaf pages contains full rows


Node pages contains indexed columns
Clusters data by Primary Key
If not Primary Key –uses Unique NonnullableIndex
If no Unique NonnullableIndex –create hidden Clustered Primary Key

Travesing B-Tree Index

104
Clustered Index

Assuming each page contains 10 rows of data

105
Clustered Index

106
Secondary Index

Clustered Index

107
Basic Indexing

Basic Indexing

Show indexes on a table


Use the SHOW INDEX and include the table name and database name.

mysql> show index from city from sakila;

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

| Table | Non_unique | Key_name | Seq_in_index | Column_name | C


ollation | Cardinality | Sub_part | Packed | Null | Index_type |
Comment | Index_comment |

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

| city | 0 | PRIMARY | 1 | city_id | A | 600 | NULL | NULL | | B


TREE | | |

| city | 1 | idx_fk_country_id | 1 | country_id | A | 109 | NULL


| NULL | | BTREE | | |

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

Or alternatively only use the SHOW INDEX FROM <TABLE NAME>

108
Basic Indexing

mysql> show index from city;

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

| Table | Non_unique | Key_name | Seq_in_index | Column_name | C


ollation | Cardinality | Sub_part | Packed | Null | Index_type |
Comment | Index_comment |

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

| city | 0 | PRIMARY | 1 | city_id | A | 600 | NULL | NULL | | B


TREE | | |

| city | 1 | idx_fk_country_id | 1 | country_id | A | 109 | NULL


| NULL | | BTREE | | |

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

Use INFORMATION_SCHEMA.STATISTICS to
show indexes
The INFORMATION_SCHEMA.STATISTICS contains index information for all tables;

109
Basic Indexing

mysql> SELECT INDEX_TYPE, NON_UNIQUE, INDEX_NAME, COLUMN_NAME, C


ARDINALITY

-> FROM INFORMATION_SCHEMA.STATISTICS

-> WHERE TABLE_NAME = 'city';

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

| INDEX_TYPE | NON_UNIQUE | INDEX_NAME | COLUMN_NAME | CARDINALI


TY |

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

| BTREE | 0 | PRIMARY | city_id | 600 |

| BTREE | 1 | idx_fk_country_id | country_id | 109 |

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

Index Usage in the WHEERE clause


Lets run the query on the film table and find all films that have a length of 100.

110
Basic Indexing

mysql> SELECT film_id, length

-> FROM film

-> WHERE length = 100;

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

| film_id | length |

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

| 65 | 100 |

| 71 | 100 |

| 221 | 100 |

| 236 | 100 |

| 322 | 100 |

| 387 | 100 |

| 399 | 100 |

| 445 | 100 |

| 681 | 100 |

| 703 | 100 |

| 979 | 100 |

| 994 | 100 |

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

111
Basic Indexing

Use EXPLAIN to analyze the query


We can use the EXPLAIN keyword to see an estimation of how the optimizer
would run the query

mysql> explain SELECT film_id, length FROM film WHERE length = 1


00;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ALL | NULL | NULL | NULL | NULL | 1


000 | 10.00 | Using where |

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

You can notive no indexes are being used for this query, in the possible_keys
column there's no index that can satisfy this query.

We can also enable profiling and see how the query was run until we got the
result sback.

Enable Profiling

mysql> set profiling = 1;

Query OK, 0 rows affected, 1 warning (0.00 sec)

Notice the warning. Oracle recommends to use the performance schema instead.

112
Basic Indexing

Run the query again and now use the SHOW PROFILES statements to see the
gathered shows.

mysql> SELECT film_id, length FROM film WHERE length = 100;

Show Gathered Profiles


You can use the SHOW PROFILES statement to show gathered profiles.

mysql> show profiles;

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

| Query_ID | Duration | Query |

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

| 1 | 0.00013000 | SELECT film_id, length FROM film WHERE length


= 100 |

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

Display Profiling Information For a Query


We can display the profiling infromation for a specific query using its query id

113
Basic Indexing

mysql> show profile for query 1;

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

| Status | Duration |

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

| starting | 0.000106 |

| Waiting for query cache lock | 0.000026 |

| starting | 0.000005 |

| checking query cache for query | 0.000016 |

| checking privileges on cached | 0.000006 |

| checking permissions | 0.000017 |

| sending cached result to clien | 0.000024 |

| cleaning up | 0.000009 |

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

We can clearly see the steps used to run this query.

Percona Toolkit pt-visual-explain


Another too we could have used is from Percona. The pt-visual-explain
takes the output of the EXPLAIN statement and visualizes it.

Install pt-visual-explain

joseph@ubuntu:~$ sudo apt-get install percona-toolkit

114
Basic Indexing

Get Visual Tree from Query


pt-visual-explain can use the file or take the result of the 'EXPLAIN'

joseph@ubuntu:~$ mysql -e "explain select film_id, length from s


akila.film where length = 100" | pt-visual-explain

Filter with WHERE

+- Table scan

rows 1000

+- Table

table film

We can notice that we are doing an index scan on the table and touching 1000
row.

Create an index
Lets create an index on the length column.

mysql> CREATE INDEX ix_film_length ON film (length);

Query OK, 0 rows affected (0.08 sec)

Records: 0 Duplicates: 0 Warnings: 0

and lets re-run our query with EXPLAIN

115
Basic Indexing

mysql> explain SELECT film_id, length FROM film WHERE length = 1


00;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ref | ix_film_length | ix_film_leng


th | 3 | const | 12 | 100.00 | Using index |

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

Notice now we are using an index on the possible_keys . The index name is
ix_film_length our newly created index. Also the extra column shows that
we are now using an index.

Lets clean up and drop the index

mysql> drop index ix_film_length on film;

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

116
Order of Indexes

Order of Indexes
Although the CREATE INDEX allows specifying the ORDER , ASC or DESC it
does not matter on an index, since the travesal is the same.

Show indexes

mysql> SHOW INDEX FROM film FROM sakila;

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

| Table | Non_unique | Key_name | Seq_in_index | Column_name | C


ollation | Cardinality | Sub_part | Packed | Null | Index_type |
Comment | Index_comment |

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

| film | 0 | PRIMARY | 1 | film_id | A | 1000 | NULL | NULL | |


BTREE | | |

| film | 1 | idx_title | 1 | title | A | 1000 | NULL | NULL | |


BTREE | | |

| film | 1 | idx_fk_language_id | 1 | language_id | A | 1 | NULL


| NULL | | BTREE | | |

| film | 1 | idx_fk_original_language_id | 1 | original_language


_id | A | 1 | NULL | NULL | YES | BTREE | | |

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

117
Order of Indexes

Query the film table

mysql> EXPLAIN SELECT film_id, length

-> FROM film

-> WHERE length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ALL | NULL | NULL | NULL | NULL | 1


000 | 10.00 | Using where |

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

You can notice no index is being used.

Add an index on film

mysql> CREATE INDEX idx_film_length ON film (length);

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

and re-run the EXPLAIN again

118
Order of Indexes

mysql> EXPLAIN SELECT film_id, length

-> FROM film

-> WHERE length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ref | idx_film_length | idx_film_le


ngth | 3 | const | 12 | 100.00 | Using index |

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

You will notice our newly created index is now being used.

Create another index and specify order


This new indexed is ordered by descending order

mysql> CREATE INDEX idx_film_length_desc ON film (length DESC);

Query OK, 0 rows affected, 1 warning (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 1

re-run the EXPLAIN

119
Order of Indexes

mysql> EXPLAIN SELECT film_id, length

-> FROM film

-> WHERE length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ref | idx_film_length,idx_film_leng


th_desc | idx_film_length | 3 | const | 12 | 100.00 | Using inde
x |

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

Notice they are now two possible indexes to satisfy this query, the
idx_file_length and idx_film_length_desc . The optimize does chose the
first one, which is by default in ascending order

Cleanup and drop the indexes


DROP INDEX idx_film_length ON film;DROP INDEX idx_film_length_desc ON
film;

120
OR Conditional with Indexes

OR Conditional with indexes


Lets use the OR in the WHERE on the file table.

mysql> EXPLAIN SELECT title, rental_duration, length

-> FROM film

-> WHERE rental_duration = 6 OR length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ALL | idx_film_length,idx_film_leng


th_desc | NULL | NULL | NULL | 1000 | 10.64 | Using where |

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

Notice they are two possible keys for the query but none of the keys was used.

Create and index for both columns

121
OR Conditional with Indexes

mysql> CREATE INDEX idx_film_rental_duration ON film (rental_dur


ation);

Query OK, 0 rows affected (0.07 sec)

Records: 0 Duplicates: 0 Warnings: 0


``

Re-run the explain again and check the results

mysql> EXPLAIN SELECT title, rental_duration, length FROM film W


HERE rental_duration = 6 OR length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ALL | idx_film_rental_duration | NU


LL | NULL | NULL | 1000 | 28.00 | Using where |

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

Notice there's a warning this time. Show warnings

mysql > show warnings;

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

122
OR Conditional with Indexes

Notice the possible key is idx_film_rental_duration and indexes are used


and we did a table scan.

Create an index on both columns


Lets create an index for both rental_duration and length

mysql> CREATE INDEX idx_film_rental_duration_length ON film (ren


tal_duration,length);

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

Notice they are now two possible keys idx_film_rental_duration and


idx_film_rental_length but no index was used to run the query. By why?

Create another index and change the order


Now we will change the order of index and check if there's an difference

mysql> CREATE INDEX idx_film_rental_duration_length ON film (ren


tal_duration,length);

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

and we also change the order of the columns in the SELECT query

123
OR Conditional with Indexes

mysql> EXPLAIN SELECT title, rental_duration, length

-> FROM film

-> WHERE rental_duration = 6 OR length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ALL | idx_film_rental_duration,idx_


film_rental_duration_length | NULL | NULL | NULL | 1000 | 28.00
| Using where |

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

and create another index

mysql> CREATE INDEX idx_film_length_rental_duration ON film (len


gth,rental_duration);

Query OK, 0 rows affected (0.03 sec)

Records: 0 Duplicates: 0 Warnings: 0

and re-run the query

124
OR Conditional with Indexes

EXPLAIN SELECT title, rental_duration, lengthFROM filmWHERE leng


th = 100 OR rental_duration = 6;

and still there's no index to satisfy the query.

Run the queries individually

125
OR Conditional with Indexes

mysql> EXPLAIN SELECT title, rental_duration, length FROM film W


HERE rental_duration = 6\G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: film

partitions: NULL

type: ref

possible_keys: idx_film_rental_duration,idx_film_rental_duration
_length

key: idx_film_rental_duration

key_len: 1

ref: const

rows: 212

filtered: 100.00

Extra: NULL

1 row in set, 1 warning (0.01 sec)

and

126
OR Conditional with Indexes

mysql> EXPLAIN SELECT title, rental_duration, length FROM film W


HERE length = 100;

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

| id | select_type | table | partitions | type | possible_keys |


key | key_len | ref | rows | filtered | Extra |

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

| 1 | SIMPLE | film | NULL | ref | idx_film_length_rental_durati


on | idx_film_length_rental_duration | 3 | const | 12 | 100.00 |
NULL |

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

Drop the indexes and clean up

DROP INDEX idx_film_length_rental_duration ON film;DROP INDEX id


x_film_rental_duration_length ON film;DROP INDEX idx_film_length
ON film;DROP INDEX idx_film_rental_duration ON film;

127

Вам также может понравиться